add in predication remapping into src, dest and branch target
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 15 Nov 2018 23:45:31 +0000 (23:45 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 15 Nov 2018 23:45:31 +0000 (23:45 +0000)
riscv/insn_template_sv.cc
riscv/sv.cc
riscv/sv_insn_redirect.cc
riscv/sv_insn_redirect.h

index 64f9fe7aa9fc767e37220add0b35a2b7f9b523f5..4389fd6e0622b127dd74e83634cb52a52fe92496 100644 (file)
@@ -51,11 +51,15 @@ reg_t sv_proc_t::FN(processor_t* p, insn_t s_insn, reg_t pc)
   // 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;
+  reg_t dest_preg = 0;
   reg_t dest_pred = ~0x0;
+  bool dest_pset = false;
   int *dest_offs = &(p->get_state()->sv().destoffs);
   bool zeroing = false;
 #ifdef INSN_CATEGORY_TWINPREDICATION
+  reg_t src_preg = 0;
   reg_t src_pred = ~0x0;
+  bool src_pset = false;
   int *src_offs = &(p->get_state()->sv().srcoffs);
   bool zeroingsrc = false;
 #endif
@@ -115,18 +119,20 @@ reg_t sv_proc_t::FN(processor_t* p, insn_t s_insn, reg_t pc)
 #endif
 #ifdef INSN_CATEGORY_TWINPREDICATION
 #ifdef INSN_TYPE_C_STACK_LD
-    src_pred = insn.predicate(sp.reg, SRC_PREDINT, zeroingsrc);
+    src_preg = sp.reg;
 #else
-    src_pred = insn.predicate(s_insn.SRC_REG(), SRC_PREDINT, zeroingsrc);
+    src_preg = s_insn.SRC_REG();
 #endif
+    src_pred = insn.predicate(src_preg, SRC_PREDINT, zeroingsrc);
 #endif
 #ifdef DEST_PREDINT
 #ifdef INSN_TYPE_C_STACK_ST
-    dest_pred = insn.predicate(sp.reg, DEST_PREDINT, zeroing);
+    dest_preg = sp.reg;
 #else
     // use the ORIGINAL, i.e. NON-REDIRECTED, register here
-    dest_pred = insn.predicate(s_insn.DEST_REG(), DEST_PREDINT, zeroing);
+    dest_preg = s_insn.DEST_REG();
 #endif
+    dest_pred = insn.predicate(dest_preg, DEST_PREDINT, zeroing);
 #endif
   }
 #if 0 // useful test at one point...
@@ -167,7 +173,8 @@ reg_t sv_proc_t::FN(processor_t* p, insn_t s_insn, reg_t pc)
 #endif
     if (!zeroingsrc)
     {
-      while ((src_pred & (1<<*src_offs)) == 0) {
+      while ((src_pset = (src_pred & (1<<pred_remap(src_preg, *src_offs))))
+                        == 0) {
           *src_offs += 1;
           if (*src_offs >= vlen) {
               break;
@@ -176,7 +183,8 @@ reg_t sv_proc_t::FN(processor_t* p, insn_t s_insn, reg_t pc)
     }
     if (!zeroing)
     {
-      while ((dest_pred & (1<<*dest_offs)) == 0) {
+      while ((dest_pset = (dest_pred & (1<<pred_remap(dest_preg, *dest_offs))))
+                        == 0) {
           *dest_offs += 1;
           if (*dest_offs >= vlen) {
               break;
index 8f24631f8a8d31bd899011a17f932ac133fa8d0e..69a4637aa48a32829e833497842bab339d8f3597 100644 (file)
@@ -279,7 +279,6 @@ uint64_t sv_insn_t::_rvc_spoffs_imm(uint64_t elwidth, uint64_t offs)
 // for use in predicated branches. sets bit N if val=true; clears bit N if false
 uint64_t sv_insn_t::rd_bitset(reg_t reg, int bit, bool set)
 {
-    reg_spec_t rs = {reg, &bit};
     uint64_t val = STATE.XPR[reg];
     if (set) {
         val |= (1UL<<bit);
@@ -304,6 +303,9 @@ void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
         fprintf(stderr, "setpc pre rd %ld v %lx pred %lx\n",
                         *target_reg, p->s.READ_REG(rs), prs1);
     }
+    if (target_reg) {
+        offs = p->s.pred_remap(*target_reg, offs);
+    }
     if ((1<<offs) & prs1)
     {
         if (target_reg) {
index 14a9d658073dd3293f50742311886480ee8e3b10..640d87460b2d4639ef201280a626ae09e21e5321 100644 (file)
@@ -121,6 +121,12 @@ union freg_shift {
     uint8_t b[sizeof(freg_t)*8];
 };
 
+unsigned int sv_proc_t::pred_remap(reg_t reg, int bit)
+{
+    reg_spec_t rs = {reg, &bit};
+    return remap(rs, true);
+}
+
 unsigned int sv_proc_t::remap(reg_spec_t const& spec, bool pred)
 {
     unsigned int offs = *spec.offset;
index e510b4e3f4ff180db76739f27aa7b1e3f093dd25..daccf0456bb03e458717e5913720e977a1163a5b 100644 (file)
@@ -266,6 +266,8 @@ public:
     sv_reg_t to_uint32(sv_float32_t const& reg);
 
     unsigned int remap(reg_spec_t const& regspec, bool pred=false);
+    unsigned int pred_remap(reg_t reg, int bit);
+
 
     bool rv_int_op_prepare(sv_reg_t const & lhs, sv_reg_t const & rhs,
                            uint64_t &vlhs, uint64_t &vrhs,