+
+void processor_t::set_pcr(int which, reg_t val)
+{
+ switch (which)
+ {
+ case PCR_SR:
+ sr = val & ~SR_ZERO; // clear SR bits that read as zero
+#ifndef RISCV_ENABLE_64BIT
+ sr &= ~(SR_S64 | SR_U64);
+#endif
+#ifndef RISCV_ENABLE_FPU
+ sr &= ~SR_EF;
+#endif
+#ifndef RISCV_ENABLE_RVC
+ sr &= ~SR_EC;
+#endif
+#ifndef RISCV_ENABLE_VEC
+ sr &= ~SR_EV;
+#endif
+ // update MMU state and flush TLB
+ mmu.set_vm_enabled(sr & SR_VM);
+ mmu.set_supervisor(sr & SR_S);
+ 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;
+ break;
+ case PCR_EVEC:
+ evec = val;
+ break;
+ case PCR_COUNT:
+ count = val;
+ break;
+ case PCR_COMPARE:
+ interrupts_pending &= ~(1 << IRQ_TIMER);
+ compare = val;
+ break;
+ case PCR_PTBR:
+ mmu.set_ptbr(val);
+ break;
+ case PCR_SEND_IPI:
+ sim.send_ipi(val);
+ break;
+ case PCR_CLR_IPI:
+ interrupts_pending &= ~(1 << IRQ_IPI);
+ break;
+ case PCR_K0:
+ pcr_k0 = val;
+ break;
+ case PCR_K1:
+ pcr_k1 = val;
+ break;
+ case PCR_VECBANK:
+ vecbanks = val & 0xff;
+ vecbanks_count = __builtin_popcountll(vecbanks);
+ break;
+ case PCR_TOHOST:
+ sim.set_tohost(val);
+ break;
+ }
+}
+
+reg_t processor_t::get_pcr(int which)
+{
+ switch (which)
+ {
+ case PCR_SR:
+ return sr;
+ case PCR_EPC:
+ return epc;
+ case PCR_BADVADDR:
+ return badvaddr;
+ case PCR_EVEC:
+ return evec;
+ case PCR_COUNT:
+ return count;
+ case PCR_COMPARE:
+ return compare;
+ case PCR_CAUSE:
+ return cause;
+ case PCR_PTBR:
+ return mmu.get_ptbr();
+ case PCR_COREID:
+ return id;
+ case PCR_IMPL:
+ return 1;
+ case PCR_K0:
+ return pcr_k0;
+ case PCR_K1:
+ return pcr_k1;
+ case PCR_VECBANK:
+ return vecbanks;
+ case PCR_TOHOST:
+ return sim.get_tohost();
+ case PCR_FROMHOST:
+ return sim.get_fromhost();
+ }
+ return -1;
+}