Implement clearing-misa.C-while-PC-is-misaligned proposal
[riscv-isa-sim.git] / riscv / execute.cc
index abffeea4f594e231882fdb9d8e539acc7699c274..c5cafc2ee5ead5df9b35f2156540f288167a3ec5 100644 (file)
@@ -43,18 +43,21 @@ static void commit_log_print_insn(state_t* state, reg_t pc, insn_t insn)
   int priv = state->last_inst_priv;
   int xlen = state->last_inst_xlen;
   int flen = state->last_inst_flen;
+
+  fprintf(stderr, "%1d ", priv);
+  commit_log_print_value(xlen, 0, pc);
+  fprintf(stderr, " (");
+  commit_log_print_value(insn.length() * 8, 0, insn.bits());
+
   if (reg.addr) {
     bool fp = reg.addr & 1;
     int rd = reg.addr >> 1;
     int size = fp ? flen : xlen;
-
-    fprintf(stderr, "%1d ", priv);
-    commit_log_print_value(xlen, 0, pc);
-    fprintf(stderr, " (");
-    commit_log_print_value(insn.length() * 8, 0, insn.bits());
     fprintf(stderr, ") %c%2d ", fp ? 'f' : 'x', rd);
     commit_log_print_value(size, reg.data.v[1], reg.data.v[0]);
     fprintf(stderr, "\n");
+  } else {
+    fprintf(stderr, ")\n");
   }
   reg.addr = 0;
 #endif
@@ -111,6 +114,7 @@ void processor_t::step(size_t n)
          default: abort(); \
        } \
        pc = state.pc; \
+       check_pc_alignment(pc); \
        break; \
      } else { \
        state.pc = pc; \
@@ -144,14 +148,12 @@ void processor_t::step(size_t n)
             break;
           }
 
-          if (unlikely(state.pc >= DEBUG_START &&
+          if (unlikely(state.pc >= DEBUG_ROM_ENTRY &&
                        state.pc < DEBUG_END)) {
             // We're waiting for the debugger to tell us something.
             return;
           }
 
-          
-          
         }
       }
       else while (instret < n)
@@ -170,13 +172,6 @@ void processor_t::step(size_t n)
         //
         // According to Andrew Waterman's recollection, this optimization
         // resulted in approximately a 2x performance increase.
-        //
-        // If there is support for compressed instructions, the mmu and the
-        // switch statement get more complicated. Each branch target is stored
-        // in the index corresponding to mmu->icache_index(), but consecutive
-        // non-branching instructions are stored in consecutive indices even if
-        // mmu->icache_index() specifies a different index (which is the case
-        // for 32-bit instructions in the presence of compressed instructions).
 
         // This figures out where to jump to in the switch statement
         size_t idx = _mmu->icache_index(pc);
@@ -192,10 +187,10 @@ void processor_t::step(size_t n)
         // is located within the execute_insn() function call.
         #define ICACHE_ACCESS(i) { \
           insn_fetch_t fetch = ic_entry->data; \
-          ic_entry++; \
           pc = execute_insn(this, pc, fetch); \
+          ic_entry = ic_entry->next; \
           if (i == mmu_t::ICACHE_ENTRIES-1) break; \
-          if (unlikely(ic_entry->tag != pc)) goto miss; \
+          if (unlikely(ic_entry->tag != pc)) break; \
           if (unlikely(instret+1 == n)) break; \
           instret++; \
           state.pc = pc; \
@@ -209,13 +204,6 @@ void processor_t::step(size_t n)
         }
 
         advance_pc();
-        continue;
-
-miss:
-        advance_pc();
-        // refill I$ if it looks like there wasn't a taken branch
-        if (pc > (ic_entry-1)->tag && pc <= (ic_entry-1)->tag + MAX_INSN_LENGTH)
-          _mmu->refill_icache(pc, ic_entry);
       }
     }
     catch(trap_t& t)