add load-reserved/store-conditional instructions
authorAndrew Waterman <waterman@cs.berkeley.edu>
Sat, 30 Mar 2013 01:35:25 +0000 (18:35 -0700)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Sat, 30 Mar 2013 01:35:25 +0000 (18:35 -0700)
13 files changed:
riscv/disasm.cc
riscv/insns/lr_d.h [new file with mode: 0644]
riscv/insns/lr_w.h [new file with mode: 0644]
riscv/insns/sc_d.h [new file with mode: 0644]
riscv/insns/sc_w.h [new file with mode: 0644]
riscv/interactive.cc
riscv/mmu.cc
riscv/mmu.h
riscv/opcodes.h
riscv/processor.cc
riscv/processor.h
riscv/sim.cc
riscv/sim.h

index c59a5dad7a0d95336771ad85ac39aa014115892a..d8c4ab0b79afc721fc8c4d426b49c8a34cb8a1f2 100644 (file)
@@ -475,6 +475,11 @@ disassembler::disassembler()
   DEFINE_XAMO(amominu_d)
   DEFINE_XAMO(amomaxu_d)
 
+  DEFINE_XAMO(lr_w)
+  DEFINE_XAMO(sc_w)
+  DEFINE_XAMO(lr_d)
+  DEFINE_XAMO(sc_d)
+
   DEFINE_FLOAD(flw)
   DEFINE_FLOAD(fld)
 
diff --git a/riscv/insns/lr_d.h b/riscv/insns/lr_d.h
new file mode 100644 (file)
index 0000000..5c8eff1
--- /dev/null
@@ -0,0 +1,2 @@
+require_xpr64;
+RD = mmu.load_reserved_int64(RS1);
diff --git a/riscv/insns/lr_w.h b/riscv/insns/lr_w.h
new file mode 100644 (file)
index 0000000..3ac4746
--- /dev/null
@@ -0,0 +1 @@
+RD = mmu.load_reserved_int32(RS1);
diff --git a/riscv/insns/sc_d.h b/riscv/insns/sc_d.h
new file mode 100644 (file)
index 0000000..a29b9f7
--- /dev/null
@@ -0,0 +1,2 @@
+require_xpr64;
+RD = mmu.store_conditional_uint64(RS1, RS2);
diff --git a/riscv/insns/sc_w.h b/riscv/insns/sc_w.h
new file mode 100644 (file)
index 0000000..caf7683
--- /dev/null
@@ -0,0 +1 @@
+RD = mmu.store_conditional_uint32(RS1, RS2);
index 3f029109cebb5624982e88ad8c2e78d447b16660..af4c0bd0e9a9fcd6953b20f6da5057640f10d9df 100644 (file)
@@ -64,10 +64,8 @@ void sim_t::interactive_run_silent(const std::string& cmd, const std::vector<std
 
 void sim_t::interactive_run(const std::string& cmd, const std::vector<std::string>& args, bool noisy)
 {
-  if (args.size())
-    step_all(atoll(args[0].c_str()), 1, noisy);
-  else
-    while (1) step_all(1, 1, noisy);
+  size_t steps = args.size() ? atoll(args[0].c_str()) : -1;
+  step(steps, noisy);
 }
 
 void sim_t::interactive_run_proc_noisy(const std::string& cmd, const std::vector<std::string>& args)
@@ -89,10 +87,8 @@ void sim_t::interactive_run_proc(const std::string& cmd, const std::vector<std::
   if(p >= (int)num_cores())
     return;
 
-  if(a.size() == 2)
-    procs[p]->step(atoi(a[1].c_str()),noisy);
-  else
-    while (1) procs[p]->step(1, noisy);
+  size_t steps = a.size() > 1 ? atoll(a[1].c_str()) : -1;
+  procs[p]->step(steps, noisy);
 }
 
 void sim_t::interactive_quit(const std::string& cmd, const std::vector<std::string>& args)
@@ -252,6 +248,6 @@ void sim_t::interactive_until(const std::string& cmd, const std::vector<std::str
     if(cmd == "while" && current != val)
       break;
 
-    step_all(1,1,false);
+    step(1, false);
   }
 }
index e95e5f9fc4734065b57bd65d44ea03a33045d2c8..3cdb21dc2b91aa84c17af1ae2d0b89c277c1ee8b 100644 (file)
@@ -6,9 +6,9 @@
 
 mmu_t::mmu_t(char* _mem, size_t _memsz)
  : mem(_mem), memsz(_memsz), badvaddr(0),
-   ptbr(0), sr(SR_S)
+   ptbr(0)
 {
-  flush_tlb();
+  set_sr(SR_S);
 }
 
 mmu_t::~mmu_t()
@@ -29,6 +29,13 @@ void mmu_t::flush_tlb()
   flush_icache();
 }
 
+void mmu_t::set_sr(uint32_t _sr)
+{
+  sr = _sr;
+  flush_tlb();
+  yield_load_reservation();
+}
+
 reg_t mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
 {
   reg_t idx = (addr >> PGSHIFT) % TLB_ENTRIES;
index 43a3ec93d750988d7e9e5ff850e18fdbea443313..a5d150f8e5a4ceed9cdf76d1527cdd9f0216505b 100644 (file)
@@ -53,6 +53,10 @@ public:
       } \
       reg_t paddr = translate(addr, sizeof(type##_t), false, false); \
       return *(type##_t*)(mem + paddr); \
+    } \
+    type##_t load_reserved_##type(reg_t addr) { \
+      load_reservation = addr; \
+      return load_##type(addr); \
     }
 
   // load value from memory at aligned address; zero extend to register width
@@ -77,6 +81,12 @@ public:
       } \
       reg_t paddr = translate(addr, sizeof(type##_t), true, false); \
       *(type##_t*)(mem + paddr) = val; \
+    } \
+    reg_t store_conditional_##type(reg_t addr, type##_t val) { \
+      if (addr == load_reservation) { \
+        store_##type(addr, val); \
+        return 0; \
+      } else return 1; \
     }
 
   // store value to memory at aligned address
@@ -148,8 +158,8 @@ public:
   // get/set the page table base register
   reg_t get_ptbr() { return ptbr; }
   void set_ptbr(reg_t addr) { ptbr = addr & ~(PGSIZE-1); flush_tlb(); }
-  // keep the MMU in sync with processor mode
-  void set_sr(uint32_t _sr) { sr = _sr; }
+  void yield_load_reservation() { load_reservation = -1; }
+  void set_sr(uint32_t sr); // keep the MMU in sync with the processor mode
 
   // flush the TLB and instruction cache
   void flush_tlb();
@@ -160,6 +170,7 @@ public:
 private:
   char* mem;
   size_t memsz;
+  reg_t load_reservation;
   reg_t badvaddr;
   reg_t ptbr;
   uint32_t sr;
index 52af654179248ce1a37c3f46d9d635b0d618b949..8ac1ab262e6cd16fd5d4183d67041f7bb79f2316 100644 (file)
@@ -2,6 +2,7 @@ DECLARE_INSN(movn, 0x6f7, 0x1ffff)
 DECLARE_INSN(vfsstw, 0x150f, 0x1ffff)
 DECLARE_INSN(remuw, 0x7bb, 0x1ffff)
 DECLARE_INSN(fmin_d, 0x180d3, 0x1ffff)
+DECLARE_INSN(lr_w, 0x1012b, 0x3fffff)
 DECLARE_INSN(vlsthu, 0x128b, 0x1ffff)
 DECLARE_INSN(c_swsp, 0x8, 0x1f)
 DECLARE_INSN(bltu, 0x363, 0x3ff)
@@ -95,6 +96,7 @@ DECLARE_INSN(blt, 0x263, 0x3ff)
 DECLARE_INSN(vsstw, 0x110f, 0x1ffff)
 DECLARE_INSN(mtfsr, 0x1f053, 0x3fffff)
 DECLARE_INSN(vssth, 0x108f, 0x1ffff)
+DECLARE_INSN(sc_w, 0x1052b, 0x1ffff)
 DECLARE_INSN(rem, 0x733, 0x1ffff)
 DECLARE_INSN(srliw, 0x29b, 0x3f83ff)
 DECLARE_INSN(lui, 0x37, 0x7f)
@@ -126,6 +128,7 @@ DECLARE_INSN(sraiw, 0x1029b, 0x3f83ff)
 DECLARE_INSN(vssegd, 0x218f, 0x1ffff)
 DECLARE_INSN(srl, 0x2b3, 0x1ffff)
 DECLARE_INSN(venqcmd, 0x2b7b, 0xf801ffff)
+DECLARE_INSN(fsub_d, 0x10d3, 0x1f1ff)
 DECLARE_INSN(vfmts, 0x1973, 0x1ffff)
 DECLARE_INSN(venqimm1, 0x2f7b, 0xf801ffff)
 DECLARE_INSN(fsgnjx_s, 0x7053, 0x1ffff)
@@ -169,7 +172,7 @@ DECLARE_INSN(c_bne, 0x11, 0x1f)
 DECLARE_INSN(fnmadd_d, 0xcf, 0x1ff)
 DECLARE_INSN(amoadd_d, 0x1ab, 0x1ffff)
 DECLARE_INSN(c_sw, 0xd, 0x1f)
-DECLARE_INSN(amomax_w, 0x152b, 0x1ffff)
+DECLARE_INSN(lr_d, 0x101ab, 0x3fffff)
 DECLARE_INSN(c_move, 0x2, 0x801f)
 DECLARE_INSN(fmovn, 0xef7, 0x1ffff)
 DECLARE_INSN(c_fsw, 0x16, 0x1f)
@@ -222,6 +225,7 @@ DECLARE_INSN(vlsegstd, 0x98b, 0xfff)
 DECLARE_INSN(vflsegd, 0x258b, 0x1ffff)
 DECLARE_INSN(vflsegw, 0x250b, 0x1ffff)
 DECLARE_INSN(vlsegsth, 0x88b, 0xfff)
+DECLARE_INSN(amomax_w, 0x152b, 0x1ffff)
 DECLARE_INSN(fsgnj_d, 0x50d3, 0x1ffff)
 DECLARE_INSN(vflsegstw, 0xd0b, 0xfff)
 DECLARE_INSN(c_sub, 0x801a, 0x801f)
@@ -237,7 +241,7 @@ DECLARE_INSN(vflsegstd, 0xd8b, 0xfff)
 DECLARE_INSN(c_add, 0x1a, 0x801f)
 DECLARE_INSN(fcvt_lu_d, 0x90d3, 0x3ff1ff)
 DECLARE_INSN(vfld, 0x58b, 0x3fffff)
-DECLARE_INSN(fsub_d, 0x10d3, 0x1f1ff)
+DECLARE_INSN(sc_d, 0x105ab, 0x1ffff)
 DECLARE_INSN(fmadd_s, 0x43, 0x1ff)
 DECLARE_INSN(fcvt_w_s, 0xa053, 0x3ff1ff)
 DECLARE_INSN(vssegh, 0x208f, 0x1ffff)
index ba65a932efee1dae61c37c86c4c671c561a616df..39a9ec096568cddf2c5ba3f0613848122a68b141 100644 (file)
@@ -225,9 +225,6 @@ void processor_t::set_pcr(int which, reg_t val)
 #endif
       sr &= ~SR_ZERO;
       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;
       break;
     case PCR_EPC:
       epc = val;
index e452df251211163782424ed5417769051dc242de..f3b2f62cd69443d1eaa0c3cfd1fbb351143ebb3c 100644 (file)
@@ -39,8 +39,6 @@ private:
   regfile_t<reg_t, NXPR, true> XPR;
   regfile_t<freg_t, NFPR, false> FPR;
   reg_t pc;
-
-  // counters
   reg_t cycle;
 
   // privileged control registers
@@ -58,9 +56,6 @@ private:
   uint32_t count;
   uint32_t compare;
 
-  // # of bits in an XPR (32 or 64). (redundant with sr)
-  int xprlen;
-
   bool run; // !reset
 
   // functions
index af51fea6505319a4529c99cbf4c0050745f01564..805429a1a257b3d15a5c5a9f3d9d090de4c65b36 100644 (file)
@@ -15,7 +15,7 @@
 
 sim_t::sim_t(int _nprocs, int mem_mb, const std::vector<std::string>& args)
   : htif(new htif_isasim_t(this, args)),
-    procs(_nprocs)
+    procs(_nprocs), current_step(0), current_proc(0)
 {
   // allocate target machine's memory, shrinking it as necessary
   // until the allocation succeeds
@@ -77,18 +77,28 @@ void sim_t::run(bool debug)
   while (!htif->done())
   {
     if(!debug)
-      step_all(10000, 1000, false);
+      step(INTERLEAVE, false);
     else
       interactive();
   }
 }
 
-void sim_t::step_all(size_t n, size_t interleave, bool noisy)
+void sim_t::step(size_t n, bool noisy)
 {
-  htif->tick();
-  for(size_t j = 0; j < n; j+=interleave)
+  for (size_t i = 0, steps = 0; i < n; i += steps)
   {
-    for(int i = 0; i < (int)num_cores(); i++)
-      procs[i]->step(interleave,noisy);
+    htif->tick();
+
+    steps = std::min(n - i, INTERLEAVE - current_step);
+    procs[current_proc]->step(steps, noisy);
+
+    current_step += steps;
+    if (current_step == INTERLEAVE)
+    {
+      current_step = 0;
+      procs[current_proc]->mmu.yield_load_reservation();
+      if (++current_proc == num_cores())
+        current_proc = 0;
+    }
   }
 }
index e3b409773a85bb8a21ef0419d9eb462e55c21c0e..2676ba4630fca844992082d18c5bcc5fc9f36f7c 100644 (file)
@@ -32,20 +32,15 @@ public:
 
 private:
   htif_isasim_t* htif;
-
-  // main memory, shared between processors
-  char* mem;
+  char* mem; // main memory
   size_t memsz; // memory size in bytes
   mmu_t* mmu; // debug port into main memory
-
-  // processors
   std::vector<processor_t*> procs;
 
-  // run each processor for n instructions; interleave instructions are
-  // run on a processor before moving on to the next processor.
-  // interleave must divide n.
-  // if noisy, print out the instructions as they execute.
-  void step_all(size_t n, size_t interleave, bool noisy);
+  void step(size_t n, bool noisy); // step through simulation
+  static const size_t INTERLEAVE = 5000;
+  size_t current_step;
+  size_t current_proc;
 
   // presents a prompt for introspection into the simulation
   void interactive();