truncate effective addresses in rv32
[riscv-isa-sim.git] / riscv / processor.cc
index e0471269ab96c400e46602beef67996773a69ad5..9f87f75c0300779d52390d120a41e2285e3cff3f 100644 (file)
@@ -24,7 +24,7 @@ processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id,
   : sim(*_sim), mmu(*_mmu), id(_id)
 {
   reset(true);
-  set_pcr(PCR_SR, sr | SR_EF | SR_EV);
+  set_pcr(PCR_SR, SR_U64 | SR_EF | SR_EV);
   utidx = _utidx;
 
   // microthreads don't possess their own microthreads
@@ -97,7 +97,7 @@ void processor_t::setvl(int vlapp)
 
 void processor_t::take_interrupt()
 {
-  uint32_t interrupts = interrupts_pending;
+  uint32_t interrupts = (sr & SR_IP) >> SR_IP_SHIFT;
   interrupts &= (sr & SR_IM) >> SR_IM_SHIFT;
 
   if(interrupts && (sr & SR_ET))
@@ -112,21 +112,19 @@ void processor_t::step(size_t n, bool noisy)
     return;
 
   size_t i = 0;
-  while(1) try
+  try
   {
     take_interrupt();
 
     mmu_t& _mmu = mmu;
-    insn_t insn;
-    insn_func_t func;
     reg_t npc = pc;
 
     // execute_insn fetches and executes one instruction
     #define execute_insn(noisy) \
       do { \
-        insn = _mmu.load_insn(npc, sr & SR_EC, &func); \
-        if(noisy) disasm(insn,pc); \
-        npc = func(this, insn, npc); \
+        mmu_t::insn_fetch_t fetch = _mmu.load_insn(npc, sr & SR_EC); \
+        if(noisy) disasm(fetch.insn, npc); \
+        npc = fetch.func(this, fetch.insn, npc); \
         pc = npc; \
       } while(0)
 
@@ -145,26 +143,20 @@ void processor_t::step(size_t n, bool noisy)
       for( ; i < n; i++)
         execute_insn(false);
     }
-
-    break;
   }
   catch(trap_t t)
   {
     // an exception occurred in the target processor
-    i++;
     take_trap(t,noisy);
   }
   catch(interrupt_t t)
   {
-    i++;
     take_trap((1ULL << (8*sizeof(reg_t)-1)) + t.i, noisy);
   }
   catch(vt_command_t cmd)
   {
     // this microthread has finished
-    i++;
     assert(cmd == vt_command_stop);
-    break;
   }
 
   cycle += i;
@@ -173,7 +165,7 @@ void processor_t::step(size_t n, bool noisy)
   uint32_t old_count = count;
   count += i;
   if(old_count < compare && uint64_t(old_count) + i >= compare)
-    interrupts_pending |= 1 << IRQ_TIMER;
+    set_interrupt(IRQ_TIMER, true);
 }
 
 void processor_t::take_trap(reg_t t, bool noisy)
@@ -229,8 +221,7 @@ void processor_t::set_pcr(int which, reg_t val)
       sr &= ~SR_EV;
 #endif
       // update MMU state and flush TLB
-      mmu.set_vm_enabled(sr & SR_VM);
-      mmu.set_supervisor(sr & SR_S);
+      mmu.set_sr(sr);
       mmu.flush_tlb();
       // set the fixed-point register length
       xprlen = ((sr & SR_S) ? (sr & SR_S64) : (sr & SR_U64)) ? 64 : 32;
@@ -245,7 +236,7 @@ void processor_t::set_pcr(int which, reg_t val)
       count = val;
       break;
     case PCR_COMPARE:
-      interrupts_pending &= ~(1 << IRQ_TIMER);
+      set_interrupt(IRQ_TIMER, false);
       compare = val;
       break;
     case PCR_PTBR:
@@ -255,10 +246,7 @@ void processor_t::set_pcr(int which, reg_t val)
       sim.send_ipi(val);
       break;
     case PCR_CLR_IPI:
-      if (val & 1)
-        interrupts_pending |= (1 << IRQ_IPI);
-      else
-        interrupts_pending &= ~(1 << IRQ_IPI);
+      set_interrupt(IRQ_IPI, val & 1);
       break;
     case PCR_K0:
       pcr_k0 = val;
@@ -275,6 +263,7 @@ void processor_t::set_pcr(int which, reg_t val)
         tohost = val;
       break;
     case PCR_FROMHOST:
+      set_interrupt(IRQ_HOST, val != 0);
       fromhost = val;
       break;
   }
@@ -317,3 +306,12 @@ reg_t processor_t::get_pcr(int which)
   }
   return -1;
 }
+
+void processor_t::set_interrupt(int which, bool on)
+{
+  uint32_t mask = (1 << (which + SR_IP_SHIFT)) & SR_IP;
+  if (on)
+    sr |= mask;
+  else
+    sr &= ~mask;
+}