[xcc] minor performance tweaks
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Sun, 12 Jun 2011 08:36:59 +0000 (01:36 -0700)
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Sun, 12 Jun 2011 08:36:59 +0000 (01:36 -0700)
riscv/decode.h
riscv/mmu.h
riscv/processor.cc
riscv/processor.h
riscv/sim.h

index 6dfe6b973a089df5304e7c642188811f34291f67..2078e58ae2cc028e1b5959a9f04ca0ce2abf4a62 100644 (file)
@@ -143,30 +143,29 @@ union insn_t
   uint32_t bits;
 };
 
-#if 0
 #include <stdio.h>
-class trace_writeback
+class do_writeback
 {
 public:
-  trace_writeback(reg_t* _rf, int _rd) : rf(_rf), rd(_rd) {}
+  do_writeback(reg_t* _rf, int _rd) : rf(_rf), rd(_rd) {}
 
-  reg_t operator = (reg_t rhs)
+  const do_writeback& operator = (reg_t rhs)
   {
+#if 0
     printf("R[%x] <= %llx\n",rd,(long long)rhs);
+#endif
     rf[rd] = rhs;
-    return rhs;
+    rf[0] = 0;
+    return *this;
   }
 
+  operator reg_t() { return rf[rd]; }
+
 private:
   reg_t* rf;
   int rd;
 };
 
-#define do_writeback(rf,rd) trace_writeback(rf,rd)
-#else
-#define do_writeback(rf,rd) rf[rd]
-#endif
-
 #define throw_illegal_instruction \
   ({ if (utmode) throw trap_vector_illegal_instruction; \
      else throw trap_illegal_instruction; })
index ef54079e1ea8b4b4bb41afaacfad3c63c92cca93..e25e90a0b61d36d8413169357f426b697232240c 100644 (file)
@@ -5,6 +5,7 @@
 #include "trap.h"
 #include "icsim.h"
 #include "common.h"
+#include "processor.h"
 
 class processor_t;
 
@@ -68,7 +69,8 @@ public:
       *(type##_t*)paddr = val; \
     }
 
-  insn_t __attribute__((always_inline)) load_insn(reg_t addr, bool rvc)
+  insn_t __attribute__((always_inline)) load_insn(reg_t addr, bool rvc,
+                                                  insn_func_t* func)
   {
     insn_t insn;
 
@@ -78,6 +80,9 @@ public:
       void* addr_lo = translate(addr, false, true);
       insn.bits = *(uint16_t*)addr_lo;
 
+      *func = processor_t::dispatch_table
+               [insn.bits % processor_t::DISPATCH_TABLE_SIZE];
+
       if(!INSN_IS_RVC(insn.bits))
       {
         void* addr_hi = translate(addr+2, false, true);
@@ -88,9 +93,10 @@ public:
     #endif
     {
       reg_t idx = (addr/sizeof(insn_t)) % ICACHE_ENTRIES;
-      bool hit = icache_tag[idx] == addr;
-      if(likely(hit))
-        return icache_data[idx];
+      insn_t data = icache_data[idx];
+      *func = icache_func[idx];
+      if(likely(icache_tag[idx] == addr))
+        return data;
 
       // the processor guarantees alignment based upon rvc mode
       void* paddr = translate(addr, false, true);
@@ -98,6 +104,8 @@ public:
 
       icache_tag[idx] = addr;
       icache_data[idx] = insn;
+      icache_func[idx] = *func = processor_t::dispatch_table
+                                 [insn.bits % processor_t::DISPATCH_TABLE_SIZE];
     }
 
     #ifdef RISCV_ENABLE_ICSIM
@@ -157,6 +165,7 @@ private:
 
   static const reg_t ICACHE_ENTRIES = 256;
   insn_t icache_data[ICACHE_ENTRIES];
+  insn_func_t icache_func[ICACHE_ENTRIES];
   reg_t icache_tag[ICACHE_ENTRIES];
 
   icsim_t* icsim;
index bb09eb50d353617e9e0bac6d4d064f2b87b63799..e86536e4b4d05192bc5b678968c8103b272f856c 100644 (file)
@@ -172,11 +172,17 @@ void processor_t::step(size_t n, bool noisy)
   {
     take_interrupt();
 
+    mmu_t& _mmu = mmu;
+    insn_t insn;
+    insn_func_t func;
+    reg_t npc = pc;
     #define execute_insn(noisy) \
-      do { insn_t insn = mmu.load_insn(pc, sr & SR_EC); \
-      if(noisy) disasm(insn,pc); \
-      pc = dispatch_table[insn.bits % DISPATCH_TABLE_SIZE](this, insn, pc); \
-      XPR[0] = 0; } while(0)
+      do { \
+        insn = _mmu.load_insn(npc, sr & SR_EC, &func); \
+        if(noisy) disasm(insn,pc); \
+        npc = func(this, insn, npc); \
+        pc = npc; \
+      } while(0)
 
     if(noisy) for( ; i < n; i++)
       execute_insn(true);
index b21663a3b1d60f31ea5fca0e54b30603d857439c..8b2d2bcee87d468b9e98bc7c3a4ed68512b25857 100644 (file)
@@ -4,12 +4,12 @@
 #include "decode.h"
 #include <cstring>
 #include "trap.h"
-#include "mmu.h"
 #include "icsim.h"
 
 #define MAX_UTS 2048
 
 class processor_t;
+class mmu_t;
 typedef reg_t (*insn_func_t)(processor_t*, insn_t, reg_t);
 class sim_t;
 
@@ -89,6 +89,7 @@ private:
   icsim_t* dtlbsim;
 
   friend class sim_t;
+  friend class mmu_t;
 
   #include "dispatch.h"
 };
index c56ad95cda772519b55cc9ef40d5de37c25f0e4c..ab388b800d876a5ad93292ff997dd7183900ddcc 100644 (file)
@@ -4,6 +4,7 @@
 #include <vector>
 #include <string>
 #include "processor.h"
+#include "mmu.h"
 
 class appserver_link_t;