From b189b9b128ce619f9423009062a85ccb17b32db9 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 29 Mar 2013 18:35:25 -0700 Subject: [PATCH] add load-reserved/store-conditional instructions --- riscv/disasm.cc | 5 +++++ riscv/insns/lr_d.h | 2 ++ riscv/insns/lr_w.h | 1 + riscv/insns/sc_d.h | 2 ++ riscv/insns/sc_w.h | 1 + riscv/interactive.cc | 14 +++++--------- riscv/mmu.cc | 11 +++++++++-- riscv/mmu.h | 15 +++++++++++++-- riscv/opcodes.h | 8 ++++++-- riscv/processor.cc | 3 --- riscv/processor.h | 5 ----- riscv/sim.cc | 24 +++++++++++++++++------- riscv/sim.h | 15 +++++---------- 13 files changed, 66 insertions(+), 40 deletions(-) create mode 100644 riscv/insns/lr_d.h create mode 100644 riscv/insns/lr_w.h create mode 100644 riscv/insns/sc_d.h create mode 100644 riscv/insns/sc_w.h diff --git a/riscv/disasm.cc b/riscv/disasm.cc index c59a5da..d8c4ab0 100644 --- a/riscv/disasm.cc +++ b/riscv/disasm.cc @@ -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 index 0000000..5c8eff1 --- /dev/null +++ b/riscv/insns/lr_d.h @@ -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 index 0000000..3ac4746 --- /dev/null +++ b/riscv/insns/lr_w.h @@ -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 index 0000000..a29b9f7 --- /dev/null +++ b/riscv/insns/sc_d.h @@ -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 index 0000000..caf7683 --- /dev/null +++ b/riscv/insns/sc_w.h @@ -0,0 +1 @@ +RD = mmu.store_conditional_uint32(RS1, RS2); diff --git a/riscv/interactive.cc b/riscv/interactive.cc index 3f02910..af4c0bd 100644 --- a/riscv/interactive.cc +++ b/riscv/interactive.cc @@ -64,10 +64,8 @@ void sim_t::interactive_run_silent(const std::string& cmd, const std::vector& 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& args) @@ -89,10 +87,8 @@ void sim_t::interactive_run_proc(const std::string& cmd, const std::vector= (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& args) @@ -252,6 +248,6 @@ void sim_t::interactive_until(const std::string& cmd, const std::vector> PGSHIFT) % TLB_ENTRIES; diff --git a/riscv/mmu.h b/riscv/mmu.h index 43a3ec9..a5d150f 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -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; diff --git a/riscv/opcodes.h b/riscv/opcodes.h index 52af654..8ac1ab2 100644 --- a/riscv/opcodes.h +++ b/riscv/opcodes.h @@ -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) diff --git a/riscv/processor.cc b/riscv/processor.cc index ba65a93..39a9ec0 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -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; diff --git a/riscv/processor.h b/riscv/processor.h index e452df2..f3b2f62 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -39,8 +39,6 @@ private: regfile_t XPR; regfile_t 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 diff --git a/riscv/sim.cc b/riscv/sim.cc index af51fea..805429a 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -15,7 +15,7 @@ sim_t::sim_t(int _nprocs, int mem_mb, const std::vector& 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; + } } } diff --git a/riscv/sim.h b/riscv/sim.h index e3b4097..2676ba4 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -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 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(); -- 2.30.2