Line 99... |
Line 99... |
int instructions;
|
int instructions;
|
|
|
/* Load and store stalls */
|
/* Load and store stalls */
|
int loadcycles, storecycles;
|
int loadcycles, storecycles;
|
|
|
|
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
|
|
static int sbuf_head = 0, sbuf_tail = 0, sbuf_count = 0;
|
|
static int sbuf_buf[MAX_SBUF_LEN] = {0};
|
|
static int sbuf_prev_cycles = 0;
|
|
|
|
/* Num cycles waiting for stores to complete */
|
|
int sbuf_wait_cyc = 0;
|
|
|
|
/* Number of total store cycles */
|
|
int sbuf_total_cyc = 0;
|
|
|
/* Local data needed for execution. */
|
/* Local data needed for execution. */
|
static struct iqueue_entry *cur;
|
static struct iqueue_entry *cur;
|
static int next_delay_insn;
|
static int next_delay_insn;
|
static int breakpoint;
|
static int breakpoint;
|
static unsigned long *op;
|
static unsigned long *op;
|
Line 459... |
Line 470... |
histexec[i] = histexec[i - 1];
|
histexec[i] = histexec[i - 1];
|
histexec[0] = icomplet[0].insn_addr; /* add last insn */
|
histexec[0] = icomplet[0].insn_addr; /* add last insn */
|
}
|
}
|
}
|
}
|
|
|
|
/* Store buffer analysis - stores are accumulated and commited when IO is idle */
|
|
static inline sbuf_store () {
|
|
int delta = cycles - sbuf_prev_cycles;
|
|
int cyc = mem_cycles;
|
|
sbuf_total_cyc += cyc;
|
|
mem_cycles = 0;
|
|
|
|
/* Take stores from buffer, that occured meanwhile */
|
|
while (delta >= sbuf_buf[sbuf_tail] && sbuf_count) {
|
|
delta -= sbuf_buf[sbuf_tail];
|
|
sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
|
|
sbuf_count--;
|
|
}
|
|
if (sbuf_count)
|
|
sbuf_buf[sbuf_tail] -= delta;
|
|
|
|
/* Store buffer is full, take one out */
|
|
if (sbuf_count >= config.cpu.sbuf_len) {
|
|
sbuf_wait_cyc += sbuf_buf[sbuf_tail];
|
|
mem_cycles += sbuf_buf[sbuf_tail];
|
|
sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
|
|
sbuf_count--;
|
|
}
|
|
/* Put newest store in the buffer */
|
|
sbuf_buf[sbuf_head] = cyc;
|
|
sbuf_head = (sbuf_head + 1) % MAX_SBUF_LEN;
|
|
sbuf_count++;
|
|
sbuf_prev_cycles = cycles;
|
|
}
|
|
|
|
/* Store buffer analysis - previous stores should commit, before any load */
|
|
static inline sbuf_load () {
|
|
/* Wait for all stores to complete */
|
|
while (sbuf_count > 0) {
|
|
sbuf_wait_cyc += sbuf_buf[sbuf_tail];
|
|
mem_cycles += sbuf_buf[sbuf_tail];
|
|
sbuf_tail = (sbuf_tail + 1) % MAX_SBUF_LEN;
|
|
sbuf_count--;
|
|
}
|
|
}
|
|
|
/* Execution logger. */
|
/* Execution logger. */
|
inline void dump_exe_log()
|
inline void dump_exe_log()
|
{
|
{
|
unsigned long i = iqueue[0].insn_addr;
|
unsigned long i = iqueue[0].insn_addr;
|
Line 623... |
Line 674... |
for (i = 0; i < MAX_GPRS; i++)
|
for (i = 0; i < MAX_GPRS; i++)
|
set_reg32 (i, 0);
|
set_reg32 (i, 0);
|
memset(iqueue, 0, sizeof(iqueue));
|
memset(iqueue, 0, sizeof(iqueue));
|
memset(icomplet, 0, sizeof(icomplet));
|
memset(icomplet, 0, sizeof(icomplet));
|
|
|
|
sbuf_head = 0;
|
|
sbuf_tail = 0;
|
|
sbuf_count = 0;
|
|
sbuf_prev_cycles = 0;
|
|
|
/* Cpu configuration */
|
/* Cpu configuration */
|
mtspr(SPR_UPR, config.cpu.upr);
|
mtspr(SPR_UPR, config.cpu.upr);
|
setsprbits(SPR_VR, SPR_VR_VER, config.cpu.ver);
|
setsprbits(SPR_VR, SPR_VR_VER, config.cpu.ver);
|
setsprbits(SPR_VR, SPR_VR_REV, config.cpu.rev);
|
setsprbits(SPR_VR, SPR_VR_REV, config.cpu.rev);
|
mtspr(SPR_SR, config.cpu.sr);
|
mtspr(SPR_SR, config.cpu.sr);
|
Line 678... |
Line 734... |
mstats.byteadd++;
|
mstats.byteadd++;
|
}
|
}
|
void l_sw() {
|
void l_sw() {
|
IFF (config.cpu.dependstats) cur->func_unit = it_store;
|
IFF (config.cpu.dependstats) cur->func_unit = it_store;
|
set_operand32(0, eval_operand32(1, &breakpoint), &breakpoint);
|
set_operand32(0, eval_operand32(1, &breakpoint), &breakpoint);
|
|
if (config.cpu.sbuf_len) sbuf_store (mem_cycles);
|
}
|
}
|
void l_sb() {
|
void l_sb() {
|
IFF (config.cpu.dependstats) cur->func_unit = it_store;
|
IFF (config.cpu.dependstats) cur->func_unit = it_store;
|
set_operand8(0, eval_operand32(1, &breakpoint), &breakpoint);
|
set_operand8(0, eval_operand32(1, &breakpoint), &breakpoint);
|
|
if (config.cpu.sbuf_len) sbuf_store (mem_cycles);
|
}
|
}
|
void l_sh() {
|
void l_sh() {
|
IFF (config.cpu.dependstats) cur->func_unit = it_store;
|
IFF (config.cpu.dependstats) cur->func_unit = it_store;
|
set_operand16(0, eval_operand32(1, &breakpoint), &breakpoint);
|
set_operand16(0, eval_operand32(1, &breakpoint), &breakpoint);
|
|
if (config.cpu.sbuf_len) sbuf_store (mem_cycles);
|
}
|
}
|
void l_lwz() {
|
void l_lwz() {
|
unsigned long val;
|
unsigned long val;
|
IFF (config.cpu.dependstats) cur->func_unit = it_load;
|
IFF (config.cpu.dependstats) cur->func_unit = it_load;
|
|
if (config.cpu.sbuf_len) sbuf_load ();
|
val = eval_operand32(1, &breakpoint);
|
val = eval_operand32(1, &breakpoint);
|
/* If eval operand produced exception don't set anything */
|
/* If eval operand produced exception don't set anything */
|
if (!pending.valid)
|
if (!pending.valid)
|
set_operand32(0, val, &breakpoint);
|
set_operand32(0, val, &breakpoint);
|
}
|
}
|
void l_lbs() {
|
void l_lbs() {
|
signed char val;
|
signed char val;
|
IFF (config.cpu.dependstats) cur->func_unit = it_load;
|
IFF (config.cpu.dependstats) cur->func_unit = it_load;
|
|
if (config.cpu.sbuf_len) sbuf_load ();
|
val = eval_operand8(1, &breakpoint);
|
val = eval_operand8(1, &breakpoint);
|
/* If eval opreand produced exception don't set anything */
|
/* If eval opreand produced exception don't set anything */
|
if (!pending.valid)
|
if (!pending.valid)
|
set_operand32(0, val, &breakpoint);
|
set_operand32(0, val, &breakpoint);
|
}
|
}
|
void l_lbz() {
|
void l_lbz() {
|
unsigned char val;
|
unsigned char val;
|
IFF (config.cpu.dependstats) cur->func_unit = it_load;
|
IFF (config.cpu.dependstats) cur->func_unit = it_load;
|
|
if (config.cpu.sbuf_len) sbuf_load ();
|
val = eval_operand8(1, &breakpoint);
|
val = eval_operand8(1, &breakpoint);
|
/* If eval opreand produced exception don't set anything */
|
/* If eval opreand produced exception don't set anything */
|
if (!pending.valid)
|
if (!pending.valid)
|
set_operand32(0, val, &breakpoint);
|
set_operand32(0, val, &breakpoint);
|
}
|
}
|
void l_lhs() {
|
void l_lhs() {
|
signed short val;
|
signed short val;
|
IFF (config.cpu.dependstats) cur->func_unit = it_load;
|
IFF (config.cpu.dependstats) cur->func_unit = it_load;
|
|
if (config.cpu.sbuf_len) sbuf_load ();
|
val = eval_operand16(1, &breakpoint);
|
val = eval_operand16(1, &breakpoint);
|
/* If eval opreand produced exception don't set anything */
|
/* If eval opreand produced exception don't set anything */
|
if (!pending.valid)
|
if (!pending.valid)
|
set_operand32(0, val, &breakpoint);
|
set_operand32(0, val, &breakpoint);
|
}
|
}
|
void l_lhz() {
|
void l_lhz() {
|
unsigned short val;
|
unsigned short val;
|
IFF (config.cpu.dependstats) cur->func_unit = it_load;
|
IFF (config.cpu.dependstats) cur->func_unit = it_load;
|
|
if (config.cpu.sbuf_len) sbuf_load ();
|
val = eval_operand16(1, &breakpoint);
|
val = eval_operand16(1, &breakpoint);
|
/* If eval opreand produced exception don't set anything */
|
/* If eval opreand produced exception don't set anything */
|
if (!pending.valid)
|
if (!pending.valid)
|
set_operand32(0, val, &breakpoint);
|
set_operand32(0, val, &breakpoint);
|
}
|
}
|