#include "sv.h"
#include "sv_decode.h"
-sv_reg_csr_entry sv_csrs[SV_CSR_SZ];
-sv_reg_entry sv_int_tb[NXPR];
-sv_reg_entry sv_fp_tb[NFPR];
-sv_pred_csr_entry sv_pred_csrs[SV_CSR_SZ];
-sv_pred_entry sv_pred_int_tb[NXPR];
-sv_pred_entry sv_pred_fp_tb[NFPR];
+sv_pred_entry* sv_insn_t::get_predentry(uint64_t reg, bool intreg)
+{
+ // okaay so first determine which map to use. intreg is passed
+ // in (ultimately) from id_regs.py's examination of the use of
+ // FRS1/RS1, WRITE_FRD/WRITE_RD, which in turn gets passed
+ // in from sv_insn_t::fimap...
+ sv_pred_entry *r;
+ if (intreg)
+ {
+ return &p->get_state()->sv_pred_int_tb[reg];
+ }
+ else
+ {
+ return &p->get_state()->sv_pred_fp_tb[reg];
+ }
+}
-bool sv_check_reg(bool intreg, uint64_t reg)
+sv_reg_entry* sv_insn_t::get_regentry(uint64_t reg, bool intreg)
{
+ // okaay so first determine which map to use. intreg is passed
+ // in (ultimately) from id_regs.py's examination of the use of
+ // FRS1/RS1, WRITE_FRD/WRITE_RD, which in turn gets passed
+ // in from sv_insn_t::fimap...
sv_reg_entry *r;
if (intreg)
{
- r = &sv_int_tb[reg];
+ return &p->get_state()->sv_int_tb[reg];
}
else
{
- r = &sv_fp_tb[reg];
+ return &p->get_state()->sv_fp_tb[reg];
}
+}
+
+bool sv_insn_t::sv_check_reg(bool intreg, uint64_t reg)
+{
+ sv_reg_entry *r = get_regentry(reg, intreg);
if (r->elwidth != 0)
{
// XXX raise exception
}
if (r->active && r->isvec)
{
+ fprintf(stderr, "checkreg: %ld active\n", reg);
return true;
}
return false;
// in (ultimately) from id_regs.py's examination of the use of
// FRS1/RS1, WRITE_FRD/WRITE_RD, which in turn gets passed
// in from sv_insn_t::fimap...
- sv_reg_entry *r;
- if (intreg)
- {
- r = &sv_int_tb[reg];
- }
- else
- {
- r = &sv_fp_tb[reg];
- }
+ sv_reg_entry *r = get_regentry(reg, intreg);
+
// next we check if this entry is active. if not, the register
// is not being "redirected", so just return the actual reg.
if (!r->active)
{
return reg; // not active: return as-is
}
+ vloop_continue = true;
// next we go through the lookup table. *THIS* is why the
// sv_reg_entry table is 32 entries (5-bit) *NOT* 6 bits
// we return the re-mapped register...
if (!r->isvec) // scalar
{
- return reg; // ... remapped at this point...
+ return reg;
}
+ vloop_continue = true;
// aaand now, as it's a "vector", FINALLY we can add on the loop-offset
// which was passed in to the sv_insn_t constructor (by reference)
// and, at last, we have "parallelism" a la contiguous registers.
reg += voffs; // wheww :)
- // however... before returning, we increment the loop-offset for
- // this particular register, so that on the next loop the next
- // contiguous register will be used.
- voffs += 1;
return reg;
}
* down to the number of bits in the predication i.e. the bitwidth of integer
* registers (i.e. XLEN bits).
*/
-reg_t sv_insn_t::predicate(processor_t *p, uint64_t reg,
- bool intreg, bool &zeroing)
+reg_t sv_insn_t::predicate(uint64_t reg, bool intreg, bool &zeroing)
{
- sv_pred_entry *r;
- if (intreg)
- {
- r = &sv_pred_int_tb[reg];
- }
- else
+ sv_reg_entry *pr = get_regentry(reg, intreg);
+ if (!pr->active)
{
- r = &sv_pred_fp_tb[reg];
+ return ~0x0; // *REGISTER* not active: return all-1s (unconditional "on")
}
+ sv_pred_entry *r = get_predentry(reg, intreg);
if (!r->active)
{
- return ~0x0; // not active: return all-1s (unconditional "on")
+ return ~0x0; // *PREDICATION* not active: return all-1s (unconditional "on")
}
zeroing = r->zero;
reg = r->regidx;
}
return predicate;
}
+
+uint64_t sv_insn_t::predicated(uint64_t reg, int offs, uint64_t pred)
+{
+ if (pred & (1<<offs))
+ {
+ return reg;
+ }
+ fprintf(stderr, "predication %ld %d %lx\n", reg, offs, pred);
+ return 0;
+}
+
+bool sv_insn_t::stop_vloop(void)
+{
+ return (p->get_state()->vl == 0) || !vloop_continue;
+}
+
+