+#include "processor.h"
#include <bfd.h>
#include <dis-asm.h>
+#include <cmath>
#include <cstdlib>
#include <iostream>
-#include "processor.h"
#include "common.h"
#include "config.h"
#include "sim.h"
+#include "softfloat.h"
processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
: sim(_sim), mmu(_mem,_memsz)
memset(R,0,sizeof(R));
memset(FR,0,sizeof(FR));
pc = 0;
- ebase = 0;
+ evec = 0;
epc = 0;
badvaddr = 0;
- set_sr(SR_S);
+ cause = 0;
+ tid = 0;
+ pcr_k0 = 0;
+ pcr_k1 = 0;
+ tohost = 0;
+ fromhost = 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));
void processor_t::set_sr(uint32_t val)
{
sr = val & ~SR_ZERO;
- if(support_64bit)
- sr |= SR_KX;
- else
- sr &= ~(SR_KX | SR_UX);
+ if(!support_64bit)
+ sr &= ~(SR_SX | SR_UX);
+ if(!support_fp)
+ sr &= ~SR_EF;
+
+ gprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32;
+}
- gprlen = ((sr & SR_S) ? (sr & SR_KX) : (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;
}
catch(trap_t t)
{
i++;
- take_trap(t);
+ take_trap(t,noisy);
}
}
-void processor_t::take_trap(trap_t t)
+void processor_t::take_trap(trap_t t, bool noisy)
{
demand(t < NUM_TRAPS, "internal error: bad trap number %d", int(t));
demand(sr & SR_ET, "error mode on core %d!\ntrap %s, pc 0x%016llx",
id, trap_name(t), (unsigned long long)pc);
+ if(noisy)
+ printf("core %3d: trap %s, pc 0x%016llx\n",
+ id, trap_name(t), (unsigned long long)pc);
set_sr((((sr & ~SR_ET) | SR_S) & ~SR_PS) | ((sr & SR_S) ? SR_PS : 0));
+ cause = t;
epc = pc;
- pc = ebase + t*128;
+ pc = evec;
badvaddr = mmu.get_badvaddr();
}