#define SR_S 0x0000000000000008ULL
#define SR_EF 0x0000000000000010ULL
#define SR_UX 0x0000000000000020ULL
-#define SR_KX 0x0000000000000040ULL
+#define SR_SX 0x0000000000000040ULL
#define SR_IM 0x000000000000FF00ULL
-#define SR_ZERO ~(SR_ET | SR_PS | SR_S | SR_EF | SR_UX | SR_KX | SR_IM)
+#define SR_ZERO ~(SR_ET | SR_PS | SR_S | SR_EF | SR_UX | SR_SX | SR_IM)
+#define SR_IM_SHIFT 8
+#define TIMER_IRQ 7
#define FP_RD_NE 0
#define FP_RD_0 1
require_supervisor;
-reg_t val = gprlen == 64 ? RA : sext32(RA);
-
switch(insn.rtype.rb)
{
case 0:
- set_sr(val);
+ set_sr(RA);
break;
case 1:
- epc = val;
+ epc = RA;
break;
case 3:
- ebase = val & ~0xFFF;
+ ebase = RA & ~0xFFF;
+ break;
+ case 4:
+ count = RA;
+ break;
+ case 5:
+ interrupts_pending &= ~(1 << TIMER_IRQ);
+ compare = RA;
break;
case 16:
- tohost = val;
- sim->set_tohost(tohost);
+ tohost = RA;
+ sim->set_tohost(RA);
break;
case 24:
- pcr_k0 = val;
+ pcr_k0 = RA;
break;
case 25:
- pcr_k1 = val;
+ pcr_k1 = RA;
break;
}
pcr_k1 = 0;
tohost = 0;
fromhost = 0;
- set_sr(SR_S | (support_64bit ? SR_KX : 0));
+ count = 0;
+ compare = 0;
+ interrupts_pending = 0;
+ set_sr(SR_S | (support_64bit ? SR_SX : 0));
set_fsr(0);
memset(counters,0,sizeof(counters));
{
sr = val & ~SR_ZERO;
if(!support_64bit)
- sr &= ~(SR_KX | SR_UX);
+ sr &= ~(SR_SX | SR_UX);
- gprlen = ((sr & SR_S) ? (sr & SR_KX) : (sr & SR_UX)) ? 64 : 32;
+ gprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
}
void processor_t::set_fsr(uint32_t val)
{
fsr = val & ~FSR_ZERO;
+ softfloat_roundingMode = (fsr & FSR_RD) >> FSR_RD_SHIFT;
}
void processor_t::step(size_t n, bool noisy)
{
for( ; i < n; i++)
{
+ uint32_t interrupts = interrupts_pending & ((sr & SR_IM) >> SR_IM_SHIFT);
+ if((sr & SR_ET) && interrupts)
+ {
+ for(int i = 0; interrupts; i++, interrupts >>= 1)
+ if(interrupts & 1)
+ throw trap_t(16+i);
+ }
+
insn_t insn = mmu.load_insn(pc);
reg_t npc = pc+sizeof(insn);
pc = npc;
R[0] = 0;
- counters[0]++;
+ if(count++ == compare)
+ interrupts_pending |= 1 << TIMER_IRQ;
}
return;
}