#define xstr(s) str(s)
#define str(s) #s
+#include "sv.h"
+
#ifdef INSN_TYPE_BRANCH
- #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs, target_pred);
+ #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs, target_reg);
#else
#define set_pc _set_pc
#endif
bool zeroingtarg = false;
#endif
sv_insn_t insn(p, bits, floatintmap, PRED_ARGS, OFFS_ARGS);
+#ifdef INSN_TYPE_BRANCH
+ sv_pred_entry *r = insn.get_predentry(s_insn.rs2(), true);
+ reg_t _target_reg = 0;
+ reg_t *target_reg = NULL;
+#endif
reg_t sp = 0;
if (vlen > 0)
{
#endif
#ifdef INSN_TYPE_BRANCH
// all branch ops are rs1, rs2. take target (dest) predicate from rs2.
- target_pred = insn.predicate(s_insn.rs2(), true, zeroingtarg);
+ if (r->active)
+ {
+ _target_reg = r->regidx;
+ target_reg = &_target_reg;
+ insn.predicate(s_insn.rs2(), true, zeroingtarg);
+ fprintf(stderr, "branch pred reg %ld pred %lx\n",
+ _target_reg, target_pred);
+ }
#endif
#ifdef INSN_CATEGORY_TWINPREDICATION
#ifdef INSN_TYPE_C_STACK_LD
if (insn.get_if_one_reg_vectorised() &&
(insn.get_saved_branch_rd() & mask) == (target_pred & mask))
{
+ fprintf(stderr, "vector branch ACTIVE\n");
_set_pc(insn.get_saved_branch_addr());
}
#endif
}
// for use in predicated branches. sets bit N if val=true; clears bit N if false
-uint64_t sv_insn_t::rd_bitset(uint64_t bit, bool set)
+uint64_t sv_insn_t::rd_bitset(reg_t reg, uint64_t bit, bool set)
{
- reg_t reg = rd();
uint64_t val = READ_REG(reg);
if (set) {
val |= (1<<bit);
}
void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
- uint64_t predicate)
+ reg_t *target_reg)
{
save_branch_addr = addr;
if (not at_least_one_reg_vectorised)
_set_pc(addr);
return;
}
- save_branch_rd = rd_bitset(offs, true);
+ if (target_reg != NULL) {
+ fprintf(stderr, "setpc pre rd %ld v %lx pred %lx\n",
+ *target_reg, READ_REG(*target_reg), prs1);
+ }
+ if ((1<<offs) & prs1)
+ {
+ if (target_reg) {
+ save_branch_rd = rd_bitset(*target_reg, offs, true);
+ } else {
+ save_branch_rd |= (1<<offs);
+ }
+ }
+ fprintf(stderr, "setpc %lx offs %ld predicate %lx rs1 %ld rs2 %ld\n",
+ save_branch_rd, offs, prs1,
+ READ_REG(rs1()), READ_REG(rs2()));
}
offs_rs2); }
void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
- uint64_t predicate);
+ reg_t *target_reg);
// used for predicated branches. sets bit N if val=true; clears bit N if false
- uint64_t rd_bitset(uint64_t bit, bool val);
+ uint64_t rd_bitset(reg_t reg, uint64_t bit, bool val);
bool sv_check_reg(bool intreg, uint64_t reg);
sv_reg_entry* get_regentry(uint64_t reg, bool isint);