Instructions are no longer member functions
authorAndrew Waterman <waterman@cs.berkeley.edu>
Mon, 12 Aug 2013 02:10:51 +0000 (19:10 -0700)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Mon, 12 Aug 2013 02:10:51 +0000 (19:10 -0700)
65 files changed:
configure
configure.ac
riscv/decode.h
riscv/htif.cc
riscv/insn_template.cc
riscv/insns/amoadd_d.h
riscv/insns/amoadd_w.h
riscv/insns/amoand_d.h
riscv/insns/amoand_w.h
riscv/insns/amomax_d.h
riscv/insns/amomax_w.h
riscv/insns/amomaxu_d.h
riscv/insns/amomaxu_w.h
riscv/insns/amomin_d.h
riscv/insns/amomin_w.h
riscv/insns/amominu_d.h
riscv/insns/amominu_w.h
riscv/insns/amoor_d.h
riscv/insns/amoor_w.h
riscv/insns/amoswap_d.h
riscv/insns/amoswap_w.h
riscv/insns/break.h
riscv/insns/clearpcr.h
riscv/insns/eret.h
riscv/insns/fence_i.h
riscv/insns/fld.h
riscv/insns/flw.h
riscv/insns/frsr.h
riscv/insns/fsd.h
riscv/insns/fssr.h
riscv/insns/fsw.h
riscv/insns/lb.h
riscv/insns/lbu.h
riscv/insns/ld.h
riscv/insns/lh.h
riscv/insns/lhu.h
riscv/insns/lr_d.h
riscv/insns/lr_w.h
riscv/insns/lw.h
riscv/insns/lwu.h
riscv/insns/mfpcr.h
riscv/insns/mtpcr.h
riscv/insns/rdcycle.h
riscv/insns/rdinstret.h
riscv/insns/rdtime.h
riscv/insns/sb.h
riscv/insns/sc_d.h
riscv/insns/sc_w.h
riscv/insns/sd.h
riscv/insns/setpcr.h
riscv/insns/sh.h
riscv/insns/slli.h
riscv/insns/srai.h
riscv/insns/srli.h
riscv/insns/sw.h
riscv/insns/syscall.h
riscv/interactive.cc
riscv/mmu.cc
riscv/mmu.h
riscv/processor.cc
riscv/processor.h
riscv/sim.cc
riscv/sim.h
riscv/trap.cc
riscv/trap.h

index 32f29c2aee9cb80dcfc15dfe5d5535cab6db9805..9340bfba494b93762aa2baf965fd4257f87c8025 100755 (executable)
--- a/configure
+++ b/configure
@@ -4004,7 +4004,7 @@ fi
 
 CFLAGS="-Wall -O2 -Wno-unused"
 
-CXXFLAGS="-Wall -O2 -std=c++0x -Wno-pmf-conversions"
+CXXFLAGS="-Wall -O2 -std=c++0x"
 
 
 #-------------------------------------------------------------------------
index bb672e608938b04d38ec1fc41ba0ec2ebf6a4c1f..335100bc78f596da344750aeb45af7b08af0bbc8 100644 (file)
@@ -72,7 +72,7 @@ AC_HEADER_STDC
 #-------------------------------------------------------------------------
 
 AC_SUBST([CFLAGS],  ["-Wall -O2 -Wno-unused"])
-AC_SUBST([CXXFLAGS],["-Wall -O2 -std=c++0x -Wno-pmf-conversions"])
+AC_SUBST([CXXFLAGS],["-Wall -O2 -std=c++0x"])
 
 #-------------------------------------------------------------------------
 # MCPPBS subproject list
index 5f65c2731da65a4db28489bb22f8013ad3bb3a62..1529927527d6319efb50dd5187d6c9acb493fe18 100644 (file)
@@ -168,14 +168,15 @@ private:
 };
 
 // helpful macros, etc
-#define RS1 XPR[insn.rtype.rs1]
-#define RS2 XPR[insn.rtype.rs2]
-#define RD XPR.write_port(insn.rtype.rd)
-#define RA XPR.write_port(1)
-#define FRS1 FPR[insn.ftype.rs1]
-#define FRS2 FPR[insn.ftype.rs2]
-#define FRS3 FPR[insn.ftype.rs3]
-#define FRD FPR.write_port(insn.ftype.rd)
+#define MMU (*p->get_mmu())
+#define RS1 p->get_state()->XPR[insn.rtype.rs1]
+#define RS2 p->get_state()->XPR[insn.rtype.rs2]
+#define RD p->get_state()->XPR.write_port(insn.rtype.rd)
+#define RA p->get_state()->XPR.write_port(1)
+#define FRS1 p->get_state()->FPR[insn.ftype.rs1]
+#define FRS2 p->get_state()->FPR[insn.ftype.rs2]
+#define FRS3 p->get_state()->FPR[insn.ftype.rs3]
+#define FRD p->get_state()->FPR.write_port(insn.ftype.rd)
 #define BIGIMM insn.ltype.bigimm
 #define SIMM insn.itype.imm12
 #define BIMM ((signed)insn.btype.immlo | (insn.btype.immhi << IMMLO_BITS))
@@ -187,23 +188,23 @@ private:
 #define ITYPE_EADDR sext_xprlen(RS1 + SIMM)
 #define BTYPE_EADDR sext_xprlen(RS1 + BIMM)
 #define RM ({ int rm = insn.ftype.rm; \
-              if(rm == 7) rm = (fsr & FSR_RD) >> FSR_RD_SHIFT; \
-              if(rm > 4) throw trap_illegal_instruction; \
+              if(rm == 7) rm = (p->get_state()->fsr & FSR_RD) >> FSR_RD_SHIFT; \
+              if(rm > 4) throw trap_illegal_instruction(); \
               rm; })
 
 #define xpr64 (xprlen == 64)
 
-#define require_supervisor if(unlikely(!(sr & SR_S))) throw trap_privileged_instruction
-#define require_xpr64 if(unlikely(!xpr64)) throw trap_illegal_instruction
-#define require_xpr32 if(unlikely(xpr64)) throw trap_illegal_instruction
+#define require_supervisor if(unlikely(!(p->get_state()->sr & SR_S))) throw trap_privileged_instruction()
+#define require_xpr64 if(unlikely(!xpr64)) throw trap_illegal_instruction()
+#define require_xpr32 if(unlikely(xpr64)) throw trap_illegal_instruction()
 #ifndef RISCV_ENABLE_FPU
-# define require_fp throw trap_illegal_instruction
+# define require_fp throw trap_illegal_instruction()
 #else
-# define require_fp if(unlikely(!(sr & SR_EF))) throw trap_fp_disabled
+# define require_fp if(unlikely(!(p->get_state()->sr & SR_EF))) throw trap_fp_disabled()
 #endif
 
 #define cmp_trunc(reg) (reg_t(reg) << (64-xprlen))
-#define set_fp_exceptions ({ set_fsr(fsr | \
+#define set_fp_exceptions ({ p->set_fsr(p->get_state()->fsr | \
                                (softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \
                              softfloat_exceptionFlags = 0; })
 
@@ -220,7 +221,7 @@ private:
 
 #define set_pc(x) \
   do { if ((x) & 3 /* For now... */) \
-         throw trap_instruction_address_misaligned; \
+         throw trap_instruction_address_misaligned(); \
        npc = (x); \
      } while(0)
 
index fc903751a0cb86eac075d78b4d74e871a0dd3ea3..679ef93f91d50f1d391917194b134fd69813dc52 100644 (file)
@@ -41,7 +41,7 @@ void htif_isasim_t::tick_once()
 
       uint64_t buf[hdr.data_size];
       for (size_t i = 0; i < hdr.data_size; i++)
-        buf[i] = sim->mmu->load_uint64((hdr.addr+i)*HTIF_DATA_ALIGN);
+        buf[i] = sim->debug_mmu->load_uint64((hdr.addr+i)*HTIF_DATA_ALIGN);
       send(buf, hdr.data_size * sizeof(buf[0]));
       break;
     }
@@ -49,7 +49,7 @@ void htif_isasim_t::tick_once()
     {
       const uint64_t* buf = (const uint64_t*)p.get_payload();
       for (size_t i = 0; i < hdr.data_size; i++)
-        sim->mmu->store_uint64((hdr.addr+i)*HTIF_DATA_ALIGN, buf[i]);
+        sim->debug_mmu->store_uint64((hdr.addr+i)*HTIF_DATA_ALIGN, buf[i]);
 
       packet_header_t ack(HTIF_CMD_ACK, seqno, 0, 0);
       send(&ack, sizeof(ack));
@@ -77,7 +77,7 @@ void htif_isasim_t::tick_once()
       send(&old_val, sizeof(old_val));
 
       if (regno == PCR_TOHOST)
-          sim->procs[coreid]->tohost = 0;
+          sim->procs[coreid]->state.tohost = 0;
 
       if (hdr.cmd == HTIF_CMD_WRITE_CONTROL_REG)
       {
index 5bd986e18be53d49e501b8d6d2275acc9aa51bd1..a901077fab798250a16285ad0ce2d49fecf7ad5d 100644 (file)
@@ -8,7 +8,7 @@
 #include "internals.h" // ditto
 #include <assert.h>
 
-reg_t processor_t::rv32_NAME(insn_t insn, reg_t pc)
+reg_t rv32_NAME(processor_t* p, insn_t insn, reg_t pc)
 {
   int xprlen = 32;
   reg_t npc = sext_xprlen(pc + insn_length(OPCODE));
@@ -16,7 +16,7 @@ reg_t processor_t::rv32_NAME(insn_t insn, reg_t pc)
   return npc;
 }
 
-reg_t processor_t::rv64_NAME(insn_t insn, reg_t pc)
+reg_t rv64_NAME(processor_t* p, insn_t insn, reg_t pc)
 {
   int xprlen = 64;
   reg_t npc = sext_xprlen(pc + insn_length(OPCODE));
index b8450bfd5038a76e7f1c762ebfa8b7f9bd08d1d5..bba975ce1fbccaf7357f02b71244bc8512dcc91a 100644 (file)
@@ -1,4 +1,4 @@
 require_xpr64;
-reg_t v = mmu.load_uint64(RS1);
-mmu.store_uint64(RS1, RS2 + v);
+reg_t v = MMU.load_uint64(RS1);
+MMU.store_uint64(RS1, RS2 + v);
 RD = v;
index 033b3c8007686667334ce7fde559c680667bf4fc..07c9c9a9e9591a7c0c0f6aacdade8b8beaefa358 100644 (file)
@@ -1,3 +1,3 @@
-reg_t v = mmu.load_int32(RS1);
-mmu.store_uint32(RS1, RS2 + v);
+reg_t v = MMU.load_int32(RS1);
+MMU.store_uint32(RS1, RS2 + v);
 RD = v;
index 586eb7fb9683ebfa6b78874de10a923e5ec936bb..1bb34029d3258cc9539dcb724f0478944e5ffeca 100644 (file)
@@ -1,4 +1,4 @@
 require_xpr64;
-reg_t v = mmu.load_uint64(RS1);
-mmu.store_uint64(RS1, RS2 & v);
+reg_t v = MMU.load_uint64(RS1);
+MMU.store_uint64(RS1, RS2 & v);
 RD = v;
index 18a92494856d83f4f846b514d6338fb74b936db7..91866dcfef7d3f46ba994c5265063c8bd279f369 100644 (file)
@@ -1,3 +1,3 @@
-reg_t v = mmu.load_int32(RS1);
-mmu.store_uint32(RS1, RS2 & v);
+reg_t v = MMU.load_int32(RS1);
+MMU.store_uint32(RS1, RS2 & v);
 RD = v;
index 1a0bc8afbcc733dbe2ce6542b921e148d11212f1..dfd2b336b02b528528242b822e6884ddb20a07c7 100644 (file)
@@ -1,4 +1,4 @@
 require_xpr64;
-sreg_t v = mmu.load_int64(RS1);
-mmu.store_uint64(RS1, std::max(sreg_t(RS2),v));
+sreg_t v = MMU.load_int64(RS1);
+MMU.store_uint64(RS1, std::max(sreg_t(RS2),v));
 RD = v;
index ff9c2da7923787f9232914074deca2008fbc36eb..1f68a8bf78c7615b61c300027ff98d99a2fe96ef 100644 (file)
@@ -1,3 +1,3 @@
-int32_t v = mmu.load_int32(RS1);
-mmu.store_uint32(RS1, std::max(int32_t(RS2),v));
+int32_t v = MMU.load_int32(RS1);
+MMU.store_uint32(RS1, std::max(int32_t(RS2),v));
 RD = v;
index ccfaf1dd1e5c7594d8e7e9f259da0c5e186d400f..8d50a0aa3031a87fbecc003c42e1a80d10f91f15 100644 (file)
@@ -1,4 +1,4 @@
 require_xpr64;
-reg_t v = mmu.load_uint64(RS1);
-mmu.store_uint64(RS1, std::max(RS2,v));
+reg_t v = MMU.load_uint64(RS1);
+MMU.store_uint64(RS1, std::max(RS2,v));
 RD = v;
index 075847d9114caa4ebaf825f504f456d5f51d99e7..d507e4f87167a30eb2121ab97fd0dee3f31656f7 100644 (file)
@@ -1,3 +1,3 @@
-uint32_t v = mmu.load_int32(RS1);
-mmu.store_uint32(RS1, std::max(uint32_t(RS2),v));
+uint32_t v = MMU.load_int32(RS1);
+MMU.store_uint32(RS1, std::max(uint32_t(RS2),v));
 RD = (int32_t)v;
index 4f3b6d6e7fb9dc11a59b1ef892478c0e304028d6..a20ace885c34fbf87cb2b2ba80536f0b6017b6f5 100644 (file)
@@ -1,4 +1,4 @@
 require_xpr64;
-sreg_t v = mmu.load_int64(RS1);
-mmu.store_uint64(RS1, std::min(sreg_t(RS2),v));
+sreg_t v = MMU.load_int64(RS1);
+MMU.store_uint64(RS1, std::min(sreg_t(RS2),v));
 RD = v;
index 529ad50c1d286d3738f6348b46b78be8b4ec8c83..d8f95af6627c4e83d316179bde716a76866e7b3c 100644 (file)
@@ -1,3 +1,3 @@
-int32_t v = mmu.load_int32(RS1);
-mmu.store_uint32(RS1, std::min(int32_t(RS2),v));
+int32_t v = MMU.load_int32(RS1);
+MMU.store_uint32(RS1, std::min(int32_t(RS2),v));
 RD = v;
index c09c51aa13052d5197c25f7e0c8f02f00f86b6bc..4f83c0f59ab878f641af434da86a654ccdfd820b 100644 (file)
@@ -1,4 +1,4 @@
 require_xpr64;
-reg_t v = mmu.load_uint64(RS1);
-mmu.store_uint64(RS1, std::min(RS2,v));
+reg_t v = MMU.load_uint64(RS1);
+MMU.store_uint64(RS1, std::min(RS2,v));
 RD = v;
index d8d637702383742b1b06956ba914b3bc3d72a965..a3a537a94f98844993daad8fea39aebcdfe498b3 100644 (file)
@@ -1,3 +1,3 @@
-uint32_t v = mmu.load_int32(RS1);
-mmu.store_uint32(RS1, std::min(uint32_t(RS2),v));
+uint32_t v = MMU.load_int32(RS1);
+MMU.store_uint32(RS1, std::min(uint32_t(RS2),v));
 RD = (int32_t)v;
index 76a45086a5498c4c2783d9c2bead0b172880fa85..87b6f2a6f6b2616026393a4f06802e6eb66330c0 100644 (file)
@@ -1,4 +1,4 @@
 require_xpr64;
-reg_t v = mmu.load_uint64(RS1);
-mmu.store_uint64(RS1, RS2 | v);
+reg_t v = MMU.load_uint64(RS1);
+MMU.store_uint64(RS1, RS2 | v);
 RD = v;
index 741fbefd9629f94a95d8fb04b87b873acc142173..0733fad203d4b9382f8fad58b759dbd418796fa9 100644 (file)
@@ -1,3 +1,3 @@
-reg_t v = mmu.load_int32(RS1);
-mmu.store_uint32(RS1, RS2 | v);
+reg_t v = MMU.load_int32(RS1);
+MMU.store_uint32(RS1, RS2 | v);
 RD = v;
index 43e353868f648976e0ba7afc849913ee6b3b4d7a..3423b91de2dab5464aad40dc6c0dbc6b17df7253 100644 (file)
@@ -1,4 +1,4 @@
 require_xpr64;
-reg_t v = mmu.load_uint64(RS1);
-mmu.store_uint64(RS1, RS2);
+reg_t v = MMU.load_uint64(RS1);
+MMU.store_uint64(RS1, RS2);
 RD = v;
index 30e6102d56db733e167d88e89e34e29a33f40b69..b888235c494173a3e92a552e2f2ef3477e339568 100644 (file)
@@ -1,3 +1,3 @@
-reg_t v = mmu.load_int32(RS1);
-mmu.store_uint32(RS1, RS2);
+reg_t v = MMU.load_int32(RS1);
+MMU.store_uint32(RS1, RS2);
 RD = v;
index 7fd3d66b1bf03e84959134551c0434dbac99d707..c22776c80278f7cd4dab81cba331f52c75fa08b8 100644 (file)
@@ -1 +1 @@
-throw trap_breakpoint;
+throw trap_breakpoint();
index 7acf221a3a07ca66e54c3bf0411f20f791a7a018..56c3584dd54ee32b9e325baa83c9ee3e985412cc 100644 (file)
@@ -1,4 +1,2 @@
 require_supervisor;
-reg_t temp = get_pcr(insn.rtype.rs1);
-set_pcr(insn.rtype.rs1, temp & ~SIMM);
-RD = temp;
+RD = p->set_pcr(insn.rtype.rs1, p->get_pcr(insn.rtype.rs1) & ~SIMM);
index 9ea8bafa4fa1e27b9bf87c3b29eed5a4abce131d..d4517eea13a8ec612bbbc57576ab941336506ce9 100644 (file)
@@ -1,5 +1,5 @@
 require_supervisor;
-set_pcr(PCR_SR, ((sr & ~(SR_S | SR_EI)) |
-                ((sr & SR_PS) ? SR_S : 0)) |
-                ((sr & SR_PEI) ? SR_EI : 0));
-set_pc(epc);
+p->set_pcr(PCR_SR, ((p->get_state()->sr & ~(SR_S | SR_EI)) |
+                ((p->get_state()->sr & SR_PS) ? SR_S : 0)) |
+                ((p->get_state()->sr & SR_PEI) ? SR_EI : 0));
+set_pc(p->get_state()->epc);
index a2dbffe1271b347559d5f75eaff20ff36774d3cb..38dcaf3fce0247d9746f81b21641c5013e8df00a 100644 (file)
@@ -1 +1 @@
-mmu.flush_icache();
+MMU.flush_icache();
index bc8b9c79dd9b5e018d8cd3fce61cfbfcd622788d..2704a4d25ad7ebee82b29aaf4f5f49f160732e06 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-FRD = mmu.load_int64(ITYPE_EADDR);
+FRD = MMU.load_int64(ITYPE_EADDR);
index 74374b90fc682305c08409ba9a94e7fd2689eb20..afab6364a1ea0fb51bf47f571e2e18160842f22c 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-FRD = mmu.load_int32(ITYPE_EADDR);
+FRD = MMU.load_int32(ITYPE_EADDR);
index 29debc40f52493eb62615f807d6c35c41e9ca5da..ef121e391d5535448a1f54d8a1c243df4abda610 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-RD = fsr;
+RD = p->get_fsr();
index 95fbd26c3862bfc417fa1e30ba263e8026f7728c..0e1c38ade5932115affba44b52ae2282db22c76a 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-mmu.store_uint64(BTYPE_EADDR, FRS2);
+MMU.store_uint64(BTYPE_EADDR, FRS2);
index cc6f9ea62ae2eb7764d73bc80a4ab120453ffed8..a9acca6c4d4b0bab34043a2bcd402fa36e7c5688 100644 (file)
@@ -1,4 +1,2 @@
 require_fp;
-uint32_t tmp = fsr;
-set_fsr(RS1);
-RD = tmp;
+RD = p->set_fsr(RS1);
index 59d9066bb91cc3e77f1f883c3318115ad9014f59..c921123f6c9a5d8c67df3299c39e2253c9f31e68 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-mmu.store_uint32(BTYPE_EADDR, FRS2);
+MMU.store_uint32(BTYPE_EADDR, FRS2);
index c88ee2db15472cf426116ac5fc9538fa7801e313..56a5f32ea6ce37ed1d8af315132872f2d1e4f48c 100644 (file)
@@ -1 +1 @@
-RD = mmu.load_int8(ITYPE_EADDR);
+RD = MMU.load_int8(ITYPE_EADDR);
index bcef96bb04d8eefc6fdd87457e75652772b882d7..66621c0653bf0198687eb1112dd95e0bb8a25467 100644 (file)
@@ -1 +1 @@
-RD = mmu.load_uint8(ITYPE_EADDR);
+RD = MMU.load_uint8(ITYPE_EADDR);
index 2bbe5c38c42e8cca58119323442aa6b2f7cc00d5..f2142946ab52eab5d71f13a4fdaf7aa721d0bcfa 100644 (file)
@@ -1,2 +1,2 @@
 require_xpr64;
-RD = mmu.load_int64(ITYPE_EADDR);
+RD = MMU.load_int64(ITYPE_EADDR);
index c04302c54d5337fa94381a00de6e1f8790068b50..fea2a8e17d94ea77bb56674ca30a313fd09536a4 100644 (file)
@@ -1 +1 @@
-RD = mmu.load_int16(ITYPE_EADDR);
+RD = MMU.load_int16(ITYPE_EADDR);
index 99d09853231241af7f74eb8d93e71855ef974e4d..71c21be48967bddd95b3adcf283f00acdae8891e 100644 (file)
@@ -1 +1 @@
-RD = mmu.load_uint16(ITYPE_EADDR);
+RD = MMU.load_uint16(ITYPE_EADDR);
index 5c8eff1090b379896bf995ba441ca67ac123f322..3d2aacee9d2946aaa20f57a8d4f49ab91220fd48 100644 (file)
@@ -1,2 +1,3 @@
 require_xpr64;
-RD = mmu.load_reserved_int64(RS1);
+p->get_state()->load_reservation = RS1;
+RD = MMU.load_int64(RS1);
index 3ac474647ac5f7f0b97d9bb9f84346c0138dbd88..7ff48ea813098c17f4ebf35a7957ebbc4037d2f0 100644 (file)
@@ -1 +1,2 @@
-RD = mmu.load_reserved_int32(RS1);
+p->get_state()->load_reservation = RS1;
+RD = MMU.load_int32(RS1);
index 639d0e7f0b34f6d8b46c9ce36cd7fe3b0cd47d6f..77f735e688bc1eb7e5a742f8d624f4fdcdcf8fa7 100644 (file)
@@ -1 +1 @@
-RD = mmu.load_int32(ITYPE_EADDR);
+RD = MMU.load_int32(ITYPE_EADDR);
index b3ebc0c97220ff59feab0c6e8f113c88831ea098..e731178eee98db120a3a3f503bd45e786e11abde 100644 (file)
@@ -1,2 +1,2 @@
 require_xpr64;
-RD = mmu.load_uint32(ITYPE_EADDR);
+RD = MMU.load_uint32(ITYPE_EADDR);
index f7aea9f4201fd651436b68f9d1fd78855a93b859..0f23426e508c3c8680ba93a33b925aa4270ffdd0 100644 (file)
@@ -1,2 +1,2 @@
 require_supervisor;
-RD = get_pcr(insn.rtype.rs1);
+RD = p->get_pcr(insn.rtype.rs1);
index 5cd0134e0ba933c08df7daebe9b953354508b747..770dfd5aab015da90f9c1abf8cd25eefdc03bb22 100644 (file)
@@ -1,4 +1,2 @@
 require_supervisor;
-reg_t val = get_pcr(insn.rtype.rs1);
-set_pcr(insn.rtype.rs1, RS2);
-RD = val;
+RD = p->set_pcr(insn.rtype.rs1, RS2);
index 9b966a683554407e2ddb44448101f2721e63e72e..7ebe9863bf1bfec81c9b9fc5e099fb6a26f0faa1 100644 (file)
@@ -1 +1 @@
-RD = cycle;
+RD = sext_xprlen(p->get_state()->cycle);
index 9b966a683554407e2ddb44448101f2721e63e72e..df56cb7d9a022fd91493440917a3f96ed76bf378 100644 (file)
@@ -1 +1 @@
-RD = cycle;
+#include "insns/rdcycle.h"
index 9b966a683554407e2ddb44448101f2721e63e72e..df56cb7d9a022fd91493440917a3f96ed76bf378 100644 (file)
@@ -1 +1 @@
-RD = cycle;
+#include "insns/rdcycle.h"
index 54176c08a873bd21f27085c394924968b5379e7f..db4d523aeb7d85b236c21a2c318c5d3ffe14e766 100644 (file)
@@ -1 +1 @@
-mmu.store_uint8(BTYPE_EADDR, RS2);
+MMU.store_uint8(BTYPE_EADDR, RS2);
index a29b9f74f4bc971a08c068638ce0db82d0751067..9ad962c6bd810736e1baf2885eba19da89a3d18d 100644 (file)
@@ -1,2 +1,8 @@
 require_xpr64;
-RD = mmu.store_conditional_uint64(RS1, RS2);
+if (RS1 == p->get_state()->load_reservation)
+{
+  MMU.store_uint64(RS1, RS2);
+  RD = 0;
+}
+else
+  RD = 1;
index caf768340215dfe9744bdebc64c7459705201d44..3ad79ac24f72241877530ddb8ed9e9bb2d98774c 100644 (file)
@@ -1 +1,7 @@
-RD = mmu.store_conditional_uint32(RS1, RS2);
+if (RS1 == p->get_state()->load_reservation)
+{
+  MMU.store_uint32(RS1, RS2);
+  RD = 0;
+}
+else
+  RD = 1;
index 558428e92fbeaf7481045907016eae910ea5be1f..24c0de9a06423498d4c8c9b45e79de6ba6987e92 100644 (file)
@@ -1,2 +1,2 @@
 require_xpr64;
-mmu.store_uint64(BTYPE_EADDR, RS2);
+MMU.store_uint64(BTYPE_EADDR, RS2);
index d645626761ea12caee6ca38d91a8eee300be0968..4a25d80bef86ef68835d2356e448a7c34043f4fc 100644 (file)
@@ -1,4 +1,2 @@
 require_supervisor;
-reg_t temp = get_pcr(insn.rtype.rs1);
-set_pcr(insn.rtype.rs1, temp | SIMM);
-RD = temp;
+RD = p->set_pcr(insn.rtype.rs1, p->get_pcr(insn.rtype.rs1) | SIMM);
index 235e50eb10a159c14fb4b721187e1d2ce3e99d0c..69234dce212e8c7a70f0aabde1ecab14804e2a11 100644 (file)
@@ -1 +1 @@
-mmu.store_uint16(BTYPE_EADDR, RS2);
+MMU.store_uint16(BTYPE_EADDR, RS2);
index bfaf4307df06497c9ed10b455f4cc8398772c031..151d97023f8be409106d7679606ec87efbd9eb5b 100644 (file)
@@ -3,6 +3,6 @@ if(xpr64)
 else
 {
   if(SHAMT & 0x20)
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
   RD = sext32(RS1 << SHAMT);
 }
index bb17d2767c6533d3be35c6069d802b53af7fb22b..7360d5fcd6cbb50022cfa2bc2c8acab1c705b5cb 100644 (file)
@@ -3,6 +3,6 @@ if(xpr64)
 else
 {
   if(SHAMT & 0x20)
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
   RD = sext32(int32_t(RS1) >> SHAMT);
 }
index 5378fd1e57118756fbf8574ff5ddeeeb5c7ed8d2..f5b8c0285bef1a9ae524cb52d7d73ed2654f33a4 100644 (file)
@@ -3,6 +3,6 @@ if(xpr64)
 else
 {
   if(SHAMT & 0x20)
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
   RD = sext32((uint32_t)RS1 >> SHAMT);
 }
index 008d8c05f09cf9eead07c68d9477f84f7d500204..81ca71dd40ed6602463a2177785a89b6cb3fc9f0 100644 (file)
@@ -1 +1 @@
-mmu.store_uint32(BTYPE_EADDR, RS2);
+MMU.store_uint32(BTYPE_EADDR, RS2);
index 2c7199debf5bd97330a08dc4650ef3b85b0ed9c3..b31b7e6dae2e010ef168294174da8bae01e1fc3c 100644 (file)
@@ -1 +1 @@
-throw trap_syscall;
+throw trap_syscall();
index fe70760a10dc3c1a6d23e35e0e8655b5d9fa401f..33efcfbc0e47559c117c70448133ca7b965765f7 100644 (file)
@@ -113,39 +113,39 @@ void sim_t::interactive_quit(const std::string& cmd, const std::vector<std::stri
 reg_t sim_t::get_pc(const std::vector<std::string>& args)
 {
   if(args.size() != 1)
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
 
   int p = atoi(args[0].c_str());
   if(p >= (int)num_cores())
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
 
-  return procs[p]->pc;
+  return procs[p]->state.pc;
 }
 
 reg_t sim_t::get_reg(const std::vector<std::string>& args)
 {
   if(args.size() != 2)
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
 
   int p = atoi(args[0].c_str());
   int r = atoi(args[1].c_str());
   if(p >= (int)num_cores() || r >= NXPR)
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
 
-  return procs[p]->XPR[r];
+  return procs[p]->state.XPR[r];
 }
 
 reg_t sim_t::get_freg(const std::vector<std::string>& args)
 {
   if(args.size() != 2)
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
 
   int p = atoi(args[0].c_str());
   int r = atoi(args[1].c_str());
   if(p >= (int)num_cores() || r >= NFPR)
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
 
-  return procs[p]->FPR[r];
+  return procs[p]->state.FPR[r];
 }
 
 void sim_t::interactive_reg(const std::string& cmd, const std::vector<std::string>& args)
@@ -177,15 +177,16 @@ void sim_t::interactive_fregd(const std::string& cmd, const std::vector<std::str
 reg_t sim_t::get_mem(const std::vector<std::string>& args)
 {
   if(args.size() != 1 && args.size() != 2)
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
 
   std::string addr_str = args[0];
+  mmu_t* mmu = debug_mmu;
   if(args.size() == 2)
   {
     int p = atoi(args[0].c_str());
     if(p >= (int)num_cores())
-      throw trap_illegal_instruction;
-    mmu->set_ptbr(procs[p]->mmu.get_ptbr());
+      throw trap_illegal_instruction();
+    mmu = procs[p]->get_mmu();
     addr_str = args[1];
   }
 
@@ -220,12 +221,12 @@ void sim_t::interactive_mem(const std::string& cmd, const std::vector<std::strin
 void sim_t::interactive_str(const std::string& cmd, const std::vector<std::string>& args)
 {
   if(args.size() != 1)
-    throw trap_illegal_instruction;
+    throw trap_illegal_instruction();
 
   reg_t addr = strtol(args[0].c_str(),NULL,16);
 
   char ch;
-  while((ch = mmu->load_uint8(addr++)))
+  while((ch = debug_mmu->load_uint8(addr++)))
     putchar(ch);
 
   putchar('\n');
index 01cbb97e9a63ecdb0677fa5cb4f1577c1a6013ee..96884d69788b24efd9612f6ae7631b7d0e655b84 100644 (file)
@@ -5,8 +5,7 @@
 #include "processor.h"
 
 mmu_t::mmu_t(char* _mem, size_t _memsz)
- : mem(_mem), memsz(_memsz), badvaddr(0),
-   ptbr(0), proc(NULL)
+ : mem(_mem), memsz(_memsz), proc(NULL)
 {
   flush_tlb();
 }
@@ -27,7 +26,6 @@ void mmu_t::flush_tlb()
   memset(tlb_store_tag, -1, sizeof(tlb_store_tag));
 
   flush_icache();
-  yield_load_reservation();
 }
 
 reg_t mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
@@ -38,7 +36,7 @@ reg_t mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
   reg_t pte = walk(addr);
 
   reg_t pte_perm = pte & PTE_PERM;
-  if (proc == NULL || (proc->sr & SR_S))
+  if (proc == NULL || (proc->state.sr & SR_S))
     pte_perm = (pte_perm/(PTE_SX/PTE_UX)) & PTE_PERM;
   pte_perm |= pte & PTE_V;
 
@@ -46,10 +44,11 @@ reg_t mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch)
   if(unlikely((pte_perm & perm) != perm))
   {
     if (fetch)
-      throw trap_instruction_access_fault;
+      throw trap_instruction_access_fault();
 
-    badvaddr = addr;
-    throw store ? trap_store_access_fault : trap_load_access_fault;
+    if (store)
+      throw trap_store_access_fault(addr);
+    throw trap_load_access_fault(addr);
   }
 
   reg_t pgoff = addr & (PGSIZE-1);
@@ -77,14 +76,14 @@ pte_t mmu_t::walk(reg_t addr)
   int shift = 8*sizeof(reg_t) - VA_BITS;
   if (((sreg_t)addr << shift >> shift) != (sreg_t)addr)
     ;
-  else if (proc == NULL || !(proc->sr & SR_VM))
+  else if (proc == NULL || !(proc->state.sr & SR_VM))
   {
     if(addr < memsz)
       pte = PTE_V | PTE_PERM | ((addr >> PGSHIFT) << PGSHIFT);
   }
   else
   {
-    reg_t base = ptbr;
+    reg_t base = proc->get_state()->ptbr;
     reg_t ptd;
 
     int ptshift = (LEVELS-1)*PTIDXBITS;
index bb35f7004b901167f173be1a406f3954fa7636db..b69de9c9020670f29e63e0bc78c5e82d8f7163b4 100644 (file)
@@ -33,16 +33,9 @@ public:
   #define load_func(type) \
     type##_t load_##type(reg_t addr) { \
       if(unlikely(addr % sizeof(type##_t))) \
-      { \
-        badvaddr = addr; \
-        throw trap_load_address_misaligned; \
-      } \
+        throw trap_load_address_misaligned(addr); \
       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
@@ -61,18 +54,9 @@ public:
   #define store_func(type) \
     void store_##type(reg_t addr, type##_t val) { \
       if(unlikely(addr % sizeof(type##_t))) \
-      { \
-        badvaddr = addr; \
-        throw trap_store_address_misaligned; \
-      } \
+        throw trap_store_address_misaligned(addr); \
       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
@@ -111,23 +95,16 @@ public:
     return icache_data[idx];
   }
 
-  reg_t get_badvaddr() { return badvaddr; }
-  reg_t get_ptbr() { return ptbr; }
-  void set_ptbr(reg_t addr) { ptbr = addr & ~(PGSIZE-1); }
   void set_processor(processor_t* p) { proc = p; flush_tlb(); }
 
   void flush_tlb();
   void flush_icache();
-  void yield_load_reservation() { load_reservation = -1; }
 
   void register_memtracer(memtracer_t*);
 
 private:
   char* mem;
   size_t memsz;
-  reg_t load_reservation;
-  reg_t badvaddr;
-  reg_t ptbr;
   processor_t* proc;
   memtracer_list_t tracer;
 
index 4dff4861e7625300da6b33a17e460743c20bcb84..0510a3dd6f6f5bd80c332acb64eae1b07c59daec 100644 (file)
@@ -19,7 +19,9 @@ processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id)
   mmu.set_processor(this);
 
   #define DECLARE_INSN(name, match, mask) \
-    register_insn(match, mask, (insn_func_t)&processor_t::rv32_##name, (insn_func_t)&processor_t::rv64_##name);
+    extern reg_t rv32_##name(processor_t*, insn_t, reg_t); \
+    extern reg_t rv64_##name(processor_t*, insn_t, reg_t); \
+    register_insn(match, mask, rv32_##name, rv64_##name);
   #include "opcodes.h"
   #undef DECLARE_INSN
 }
@@ -28,17 +30,15 @@ processor_t::~processor_t()
 {
 }
 
-void processor_t::reset(bool value)
+void state_t::reset()
 {
-  if (run == !value)
-    return;
-  run = !value;
-
   // the ISA guarantees on boot that the PC is 0x2000 and the the processor
   // is in supervisor mode, and in 64-bit mode, if supported, with traps
   // and virtual memory disabled.
-  sr = 0;
-  set_pcr(PCR_SR, SR_S | SR_S64 | SR_IM);
+  sr = SR_S;
+#ifdef RISCV_ENABLE_64BIT
+  sr |= SR_S64;
+#endif
   pc = 0x2000;
 
   // the following state is undefined upon boot-up,
@@ -55,23 +55,36 @@ void processor_t::reset(bool value)
   count = 0;
   compare = 0;
   cycle = 0;
-  set_fsr(0);
+  fsr = 0;
+
+  load_reservation = -1;
+}
+
+void processor_t::reset(bool value)
+{
+  if (run == !value)
+    return;
+  run = !value;
+
+  state.reset();
 }
 
-void processor_t::set_fsr(uint32_t val)
+uint32_t processor_t::set_fsr(uint32_t val)
 {
-  fsr = val & ~FSR_ZERO; // clear FSR bits that read as zero
+  uint32_t old_fsr = state.fsr;
+  state.fsr = val & ~FSR_ZERO; // clear FSR bits that read as zero
+  return old_fsr;
 }
 
 void processor_t::take_interrupt()
 {
-  uint32_t interrupts = (sr & SR_IP) >> SR_IP_SHIFT;
-  interrupts &= (sr & SR_IM) >> SR_IM_SHIFT;
+  uint32_t interrupts = (state.sr & SR_IP) >> SR_IP_SHIFT;
+  interrupts &= (state.sr & SR_IM) >> SR_IM_SHIFT;
 
-  if(interrupts && (sr & SR_EI))
-    for(int i = 0; ; i++, interrupts >>= 1)
-      if(interrupts & 1)
-        throw interrupt_t(i);
+  if (interrupts && (state.sr & SR_EI))
+    for (int i = 0; ; i++, interrupts >>= 1)
+      if (interrupts & 1)
+        throw trap_t((1ULL << ((state.sr & SR_S64) ? 63 : 31)) + i);
 }
 
 void processor_t::step(size_t n, bool noisy)
@@ -80,20 +93,19 @@ void processor_t::step(size_t n, bool noisy)
     return;
 
   size_t i = 0;
+  reg_t npc = state.pc;
+  mmu_t& _mmu = mmu;
+
   try
   {
     take_interrupt();
 
-    mmu_t& _mmu = mmu;
-    reg_t npc = pc;
-
     // execute_insn fetches and executes one instruction
     #define execute_insn(noisy) \
       do { \
         mmu_t::insn_fetch_t fetch = _mmu.load_insn(npc); \
         if(noisy) disasm(fetch.insn, npc); \
         npc = fetch.func(this, fetch.insn, npc); \
-        pc = npc; \
       } while(0)
 
     if(noisy) for( ; i < n; i++) // print out instructions as we go
@@ -111,46 +123,45 @@ void processor_t::step(size_t n, bool noisy)
       for( ; i < n; i++)
         execute_insn(false);
     }
+
+    state.pc = npc;
   }
-  catch(trap_t t)
-  {
-    // an exception occurred in the target processor
-    take_trap(t,noisy);
-  }
-  catch(interrupt_t t)
+  catch(trap_t& t)
   {
-    take_trap((1ULL << ((sr & SR_S64) ? 63 : 31)) + t.i, noisy);
+    take_trap(npc, t, noisy);
   }
 
-  cycle += i;
+  state.cycle += i;
 
   // update timer and possibly register a timer interrupt
-  uint32_t old_count = count;
-  count += i;
-  if(old_count < compare && uint64_t(old_count) + i >= compare)
+  uint32_t old_count = state.count;
+  state.count += i;
+  if(old_count < state.compare && uint64_t(old_count) + i >= state.compare)
     set_interrupt(IRQ_TIMER, true);
 }
 
-void processor_t::take_trap(reg_t t, bool noisy)
+void processor_t::take_trap(reg_t pc, trap_t& t, bool noisy)
 {
   if(noisy)
   {
-    if ((sreg_t)t < 0)
+    if ((sreg_t)t.cause() < 0)
       fprintf(stderr, "core %3d: interrupt %d, epc 0x%016" PRIx64 "\n",
-              id, uint8_t(t), pc);
+              id, uint8_t(t.cause()), pc);
     else
       fprintf(stderr, "core %3d: trap %s, epc 0x%016" PRIx64 "\n",
-              id, trap_name(trap_t(t)), pc);
+              id, t.name(), pc);
   }
 
-  // switch to supervisor, set previous supervisor bit, disable traps
-  set_pcr(PCR_SR, (((sr & ~SR_EI) | SR_S) & ~SR_PS & ~SR_PEI) |
-                  ((sr & SR_S) ? SR_PS : 0) |
-                  ((sr & SR_EI) ? SR_PEI : 0));
-  cause = t;
-  epc = pc;
-  pc = evec;
-  badvaddr = mmu.get_badvaddr();
+  // switch to supervisor, set previous supervisor bit, disable interrupts
+  set_pcr(PCR_SR, (((state.sr & ~SR_EI) | SR_S) & ~SR_PS & ~SR_PEI) |
+                  ((state.sr & SR_S) ? SR_PS : 0) |
+                  ((state.sr & SR_EI) ? SR_PEI : 0));
+  yield_load_reservation();
+  state.cause = t.cause();
+  state.epc = pc;
+  state.pc = state.evec;
+
+  t.side_effects(&state); // might set badvaddr etc.
 }
 
 void processor_t::deliver_ipi()
@@ -164,42 +175,44 @@ void processor_t::disasm(insn_t insn, reg_t pc)
   // the disassembler is stateless, so we share it
   static disassembler disasm;
   fprintf(stderr, "core %3d: 0x%016" PRIx64 " (0x%08" PRIxFAST32 ") %s\n",
-          id, pc, insn.bits, disasm.disassemble(insn).c_str());
+          id, state.pc, insn.bits, disasm.disassemble(insn).c_str());
 }
 
-void processor_t::set_pcr(int which, reg_t val)
+reg_t processor_t::set_pcr(int which, reg_t val)
 {
+  reg_t old_pcr = get_pcr(which);
+
   switch (which)
   {
     case PCR_SR:
-      sr = (val & ~SR_IP) | (sr & SR_IP);
+      state.sr = (val & ~SR_IP) | (state.sr & SR_IP);
 #ifndef RISCV_ENABLE_64BIT
-      sr &= ~(SR_S64 | SR_U64);
+      state.sr &= ~(SR_S64 | SR_U64);
 #endif
 #ifndef RISCV_ENABLE_FPU
-      sr &= ~SR_EF;
+      state.sr &= ~SR_EF;
 #endif
 #ifndef RISCV_ENABLE_VEC
-      sr &= ~SR_EV;
+      state.sr &= ~SR_EV;
 #endif
-      sr &= ~SR_ZERO;
+      state.sr &= ~SR_ZERO;
       mmu.flush_tlb();
       break;
     case PCR_EPC:
-      epc = val;
+      state.epc = val;
       break;
     case PCR_EVEC: 
-      evec = val;
+      state.evec = val;
       break;
     case PCR_COUNT:
-      count = val;
+      state.count = val;
       break;
     case PCR_COMPARE:
       set_interrupt(IRQ_TIMER, false);
-      compare = val;
+      state.compare = val;
       break;
     case PCR_PTBR:
-      mmu.set_ptbr(val);
+      state.ptbr = val & ~(PGSIZE-1);
       break;
     case PCR_SEND_IPI:
       sim.send_ipi(val);
@@ -208,20 +221,22 @@ void processor_t::set_pcr(int which, reg_t val)
       set_interrupt(IRQ_IPI, val & 1);
       break;
     case PCR_K0:
-      pcr_k0 = val;
+      state.pcr_k0 = val;
       break;
     case PCR_K1:
-      pcr_k1 = val;
+      state.pcr_k1 = val;
       break;
     case PCR_TOHOST:
-      if (tohost == 0)
-        tohost = val;
+      if (state.tohost == 0)
+        state.tohost = val;
       break;
     case PCR_FROMHOST:
       set_interrupt(IRQ_HOST, val != 0);
-      fromhost = val;
+      state.fromhost = val;
       break;
   }
+
+  return old_pcr;
 }
 
 reg_t processor_t::get_pcr(int which)
@@ -229,37 +244,38 @@ reg_t processor_t::get_pcr(int which)
   switch (which)
   {
     case PCR_SR:
-      return sr;
+      return state.sr;
     case PCR_EPC:
-      return epc;
+      return state.epc;
     case PCR_BADVADDR:
-      return badvaddr;
+      return state.badvaddr;
     case PCR_EVEC:
-      return evec;
+      return state.evec;
     case PCR_COUNT:
-      return count;
+      return state.count;
     case PCR_COMPARE:
-      return compare;
+      return state.compare;
     case PCR_CAUSE:
-      return cause;
+      return state.cause;
     case PCR_PTBR:
-      return mmu.get_ptbr();
+      return state.ptbr;
     case PCR_ASID:
       return 0;
     case PCR_FATC:
       mmu.flush_tlb();
+      return 0;
     case PCR_HARTID:
       return id;
     case PCR_IMPL:
       return 1;
     case PCR_K0:
-      return pcr_k0;
+      return state.pcr_k0;
     case PCR_K1:
-      return pcr_k1;
+      return state.pcr_k1;
     case PCR_TOHOST:
-      return tohost;
+      return state.tohost;
     case PCR_FROMHOST:
-      return fromhost;
+      return state.fromhost;
   }
   return -1;
 }
@@ -268,27 +284,26 @@ void processor_t::set_interrupt(int which, bool on)
 {
   uint32_t mask = (1 << (which + SR_IP_SHIFT)) & SR_IP;
   if (on)
-    sr |= mask;
+    state.sr |= mask;
   else
-    sr &= ~mask;
+    state.sr &= ~mask;
+}
+
+static reg_t illegal_instruction(processor_t* p, insn_t insn, reg_t pc)
+{
+  throw trap_illegal_instruction();
 }
 
 insn_func_t processor_t::decode_insn(insn_t insn)
 {
-  bool rv64 = (sr & SR_S) ? (sr & SR_S64) : (sr & SR_U64);
+  bool rv64 = (state.sr & SR_S) ? (state.sr & SR_S64) : (state.sr & SR_U64);
 
   auto key = insn.bits & ((1L << opcode_bits)-1);
-  auto it = opcode_map.find(key);
   for (auto it = opcode_map.find(key); it != opcode_map.end() && it->first == key; ++it)
     if ((insn.bits & it->second.mask) == it->second.match)
       return rv64 ? it->second.rv64 : it->second.rv32;
 
-  return &processor_t::illegal_instruction;
-}
-
-reg_t processor_t::illegal_instruction(insn_t insn, reg_t pc)
-{
-  throw trap_illegal_instruction;
+  return &illegal_instruction;
 }
 
 void processor_t::register_insn(uint32_t match, uint32_t mask, insn_func_t rv32, insn_func_t rv64)
index e21901c480adca74cb6a316848d3f75137d957d7..7b7f31407eb414cdfb66c581162dcab96529e3fa 100644 (file)
@@ -5,7 +5,6 @@
 
 #include "decode.h"
 #include <cstring>
-#include "trap.h"
 #include "config.h"
 #include <map>
 
@@ -13,30 +12,14 @@ class processor_t;
 class mmu_t;
 typedef reg_t (*insn_func_t)(processor_t*, insn_t, reg_t);
 class sim_t;
+class trap_t;
 
-// this class represents one processor in a RISC-V machine.
-class processor_t
+// architectural state of a RISC-V hart
+struct state_t
 {
-public:
-  processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id);
-  ~processor_t();
-
-  void reset(bool value);
-  void step(size_t n, bool noisy); // run for n cycles
-  void deliver_ipi(); // register an interprocessor interrupt
-  bool running() { return run; }
-  void set_pcr(int which, reg_t val);
-  void set_interrupt(int which, bool on);
-  reg_t get_pcr(int which);
-  mmu_t* get_mmu() { return &mmu; }
-
-  void register_insn(uint32_t match, uint32_t mask, insn_func_t rv32, insn_func_t rv64);
+  void reset();
 
-private:
-  sim_t& sim;
-  mmu_t& mmu; // main memory is always accessed via the mmu
-
-  // user-visible architected state
+  // user-visible state
   reg_t pc;
   regfile_t<reg_t, NXPR, true> XPR;
   regfile_t<freg_t, NFPR, false> FPR;
@@ -46,17 +29,47 @@ private:
   reg_t epc;
   reg_t badvaddr;
   reg_t evec;
+  reg_t ptbr;
   reg_t pcr_k0;
   reg_t pcr_k1;
   reg_t cause;
   reg_t tohost;
   reg_t fromhost;
-  uint32_t id;
   uint32_t sr; // only modify the status register using set_pcr()
   uint32_t fsr;
   uint32_t count;
   uint32_t compare;
 
+  reg_t load_reservation;
+};
+
+// this class represents one processor in a RISC-V machine.
+class processor_t
+{
+public:
+  processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id);
+  ~processor_t();
+
+  void reset(bool value);
+  void step(size_t n, bool noisy); // run for n cycles
+  void deliver_ipi(); // register an interprocessor interrupt
+  bool running() { return run; }
+  reg_t set_pcr(int which, reg_t val);
+  uint32_t set_fsr(uint32_t val); // set the floating-point status register
+  void set_interrupt(int which, bool on);
+  reg_t get_pcr(int which);
+  uint32_t get_fsr() { return state.fsr; }
+  mmu_t* get_mmu() { return &mmu; }
+  state_t* get_state() { return &state; }
+  void yield_load_reservation() { state.load_reservation = (reg_t)-1; }
+
+  void register_insn(uint32_t match, uint32_t mask, insn_func_t rv32, insn_func_t rv64);
+
+private:
+  sim_t& sim;
+  mmu_t& mmu; // main memory is always accessed via the mmu
+  state_t state;
+  uint32_t id;
   bool run; // !reset
 
   struct opcode_map_entry_t
@@ -70,22 +83,14 @@ private:
   std::multimap<uint32_t, opcode_map_entry_t> opcode_map;
 
   void take_interrupt(); // take a trap if any interrupts are pending
-  void set_fsr(uint32_t val); // set the floating-point status register
-  void take_trap(reg_t t, bool noisy); // take an exception
+  void take_trap(reg_t pc, trap_t& t, bool noisy); // take an exception
   void disasm(insn_t insn, reg_t pc); // disassemble and print an instruction
 
   friend class sim_t;
   friend class mmu_t;
   friend class htif_isasim_t;
 
-  #define DECLARE_INSN(name, match, mask) \
-    reg_t rv32_ ## name(insn_t insn, reg_t pc); \
-    reg_t rv64_ ## name(insn_t insn, reg_t pc);
-  #include "opcodes.h"
-  #undef DECLARE_INSN
-
   insn_func_t decode_insn(insn_t insn);
-  reg_t illegal_instruction(insn_t insn, reg_t pc);
 };
 
 #endif
index 6534900750547e16dc68f7caeca986cdf613b13a..2ac326698f5a1292ef845e71582b7425a20156d7 100644 (file)
@@ -18,9 +18,9 @@ static void handle_signal(int sig)
   signal(sig, &handle_signal);
 }
 
-sim_t::sim_t(size_t _nprocs, size_t mem_mb, const std::vector<std::string>& args)
-  : htif(new htif_isasim_t(this, args)),
-    procs(_nprocs), current_step(0), current_proc(0), debug(false)
+sim_t::sim_t(size_t nprocs, size_t mem_mb, const std::vector<std::string>& args)
+  : htif(new htif_isasim_t(this, args)), procs(std::max(nprocs, size_t(1))),
+    current_step(0), current_proc(0), debug(false)
 {
   signal(SIGINT, &handle_signal);
   // allocate target machine's memory, shrinking it as necessary
@@ -38,11 +38,9 @@ sim_t::sim_t(size_t _nprocs, size_t mem_mb, const std::vector<std::string>& args
     fprintf(stderr, "warning: only got %lu bytes of target mem (wanted %lu)\n",
             (unsigned long)memsz, (unsigned long)memsz0);
 
-  mmu = new mmu_t(mem, memsz);
+  debug_mmu = new mmu_t(mem, memsz);
 
-  if (_nprocs == 0)
-    _nprocs = 1;
-  for (size_t i = 0; i < _nprocs; i++)
+  for (size_t i = 0; i < procs.size(); i++)
     procs[i] = new processor_t(this, new mmu_t(mem, memsz), i);
 }
 
@@ -54,7 +52,7 @@ sim_t::~sim_t()
     delete procs[i];
     delete pmmu;
   }
-  delete mmu;
+  delete debug_mmu;
   free(mem);
 }
 
@@ -100,7 +98,7 @@ void sim_t::step(size_t n, bool noisy)
     if (current_step == INTERLEAVE)
     {
       current_step = 0;
-      procs[current_proc]->mmu.yield_load_reservation();
+      procs[current_proc]->yield_load_reservation();
       if (++current_proc == procs.size())
         current_proc = 0;
     }
@@ -117,7 +115,7 @@ bool sim_t::running()
 
 void sim_t::stop()
 {
-  procs[0]->tohost = 1;
+  procs[0]->state.tohost = 1;
   while (!htif->done())
     htif->tick();
 }
index a53f3f0f65102cd7602e4ad7ec54f945b7325314..bcb7c1c9c7361abfc0cce39a6f2748d827bfd150 100644 (file)
@@ -38,7 +38,7 @@ private:
   std::auto_ptr<htif_isasim_t> htif;
   char* mem; // main memory
   size_t memsz; // memory size in bytes
-  mmu_t* mmu; // debug port into main memory
+  mmu_t* debug_mmu;  // debug port into main memory
   std::vector<processor_t*> procs;
 
   void step(size_t n, bool noisy); // step through simulation
index ba0d867e2c7a94d9f3c9855602978f637ce6fead..ead3a0047c6cdab0abe24121007da8791e3417f6 100644 (file)
@@ -1,12 +1,15 @@
-// See LICENSE for license details.
-
 #include "trap.h"
+#include "processor.h"
+#include <cstdio>
 
-const char* trap_name(trap_t t)
+const char* trap_t::name()
 {
-  #define DECLARE_TRAP(x) "trap_"#x
-  static const char* names[] = { TRAP_LIST };
-  #undef DECLARE_TRAP
+  const char* fmt = uint8_t(which) == which ? "trap #%u" : "interrupt #%u";
+  sprintf(_name, fmt, uint8_t(which));
+  return _name;
+}
 
-  return (unsigned)t >= sizeof(names)/sizeof(names[0]) ? "unknown" : names[t];
+void mem_trap_t::side_effects(state_t* state)
+{
+  state->badvaddr = badvaddr;
 }
index 6448e51cf67a061a190500bead2d79af707cd1a4..a7a823bcd3fc6479bfd9023dfb3ec99befaf56d0 100644 (file)
@@ -3,35 +3,58 @@
 #ifndef _RISCV_TRAP_H
 #define _RISCV_TRAP_H
 
-#define TRAP_LIST \
-  DECLARE_TRAP(instruction_address_misaligned), \
-  DECLARE_TRAP(instruction_access_fault), \
-  DECLARE_TRAP(illegal_instruction), \
-  DECLARE_TRAP(privileged_instruction), \
-  DECLARE_TRAP(fp_disabled), \
-  DECLARE_TRAP(reserved0), \
-  DECLARE_TRAP(syscall), \
-  DECLARE_TRAP(breakpoint), \
-  DECLARE_TRAP(load_address_misaligned), \
-  DECLARE_TRAP(store_address_misaligned), \
-  DECLARE_TRAP(load_access_fault), \
-  DECLARE_TRAP(store_access_fault), \
-  DECLARE_TRAP(vector_disabled), \
-  DECLARE_TRAP(vector_bank), \
-  DECLARE_TRAP(vector_illegal_instruction), \
-  DECLARE_TRAP(reserved1), \
-
-#define DECLARE_TRAP(x) trap_##x
-enum trap_t
+#include "decode.h"
+
+class state_t;
+
+class trap_t
+{
+ public:
+  trap_t(reg_t which) : which(which) {}
+  virtual const char* name();
+  virtual void side_effects(state_t* state) {}
+  reg_t cause() { return which; }
+ private:
+  char _name[16];
+  reg_t which;
+};
+
+class mem_trap_t : public trap_t
 {
-  TRAP_LIST
-  NUM_TRAPS
+ public:
+  mem_trap_t(reg_t which, reg_t badvaddr)
+    : trap_t(which), badvaddr(badvaddr) {}
+  void side_effects(state_t* state);
+ private:
+  reg_t badvaddr;
+};
+
+#define DECLARE_TRAP(n, x) class trap_##x : public trap_t { \
+ public: \
+  trap_##x() : trap_t(n) {} \
+  const char* name() { return "trap_"#x; } \
 };
-#undef DECLARE_TRAP
 
-struct interrupt_t { interrupt_t(int which) : i(which) {} int i; };
-struct halt_t {}; // thrown to stop the processor from running
+#define DECLARE_MEM_TRAP(n, x) class trap_##x : public mem_trap_t { \
+ public: \
+  trap_##x(reg_t badvaddr) : mem_trap_t(n, badvaddr) {} \
+  const char* name() { return "trap_"#x; } \
+};
 
-extern "C" const char* trap_name(trap_t t);
+DECLARE_TRAP(0, instruction_address_misaligned)
+DECLARE_TRAP(1, instruction_access_fault)
+DECLARE_TRAP(2, illegal_instruction)
+DECLARE_TRAP(3, privileged_instruction)
+DECLARE_TRAP(4, fp_disabled)
+DECLARE_TRAP(5, reserved0)
+DECLARE_TRAP(6, syscall)
+DECLARE_TRAP(7, breakpoint)
+DECLARE_MEM_TRAP(8, load_address_misaligned)
+DECLARE_MEM_TRAP(9, store_address_misaligned)
+DECLARE_MEM_TRAP(10, load_access_fault)
+DECLARE_MEM_TRAP(11, store_access_fault)
+DECLARE_TRAP(12, vector_disabled)
+DECLARE_TRAP(13, vector_bank)
+DECLARE_TRAP(14, vector_illegal_instruction)
 
 #endif