URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 712 to Rev 713
- ↔ Reverse comparison
Rev 712 → Rev 713
/trunk/or1ksim/sim-config.h
194,7 → 194,6
int superscalar; /* superscalara analysis */ |
int hazards; /* dependency hazards analysis */ |
int dependstats; /* dependency statistics */ |
int raw_range; /* raw register usage over time stats; range in cycles, 0 = disabled */ |
int sbuf_len; /* length of store buffer, zero if disabled */ |
} cpu; |
|
/trunk/or1ksim/cpu/or32/execute.c
41,17 → 41,6
#include "sim-config.h" |
#include "debug_unit.h" |
|
/* Whether instructions set overflow flag */ |
#define SET_OV_FLAG 1 |
|
/* Whether arithmethic instructions set flag on zero */ |
#define ARITH_SET_FLAG 1 |
|
/* Specifies, whether we should use generated decode_execute or |
runtime generated. In latter case file 'insnset.c' is included |
at the bottom of this file */ |
//#define SIMPLE_EXECUTION 1 |
|
/* General purpose registers. */ |
machword reg[MAX_GPRS]; |
|
121,7 → 110,6
int sbuf_total_cyc = 0; |
|
/* Local data needed for execution. */ |
static struct iqueue_entry *cur; |
static int next_delay_insn; |
static int breakpoint; |
static unsigned long *op; |
163,11 → 151,11
inline static unsigned long eval_reg32(int regno) |
{ |
if (regno < MAX_GPRS) { |
IFF(config.cpu.raw_range) { |
#if RAW_RANGE_STATS |
int delta = (cycles - raw_stats.reg[regno]); |
if ((unsigned long)delta < (unsigned long)config.cpu.raw_range) |
if ((unsigned long)delta < (unsigned long)MAX_RAW_RANGE) |
raw_stats.range[delta]++; |
} |
#endif /* RAW_RANGE */ |
return reg[regno]; |
} else { |
printf("\nABORT: read out of registers\n"); |
195,8 → 183,9
|
if (regno < MAX_GPRS) { |
reg[regno] = value; |
IFF(config.cpu.raw_range) |
raw_stats.reg[regno] = cycles; |
#if RAW_RANGE_STATS |
raw_stats.reg[regno] = cycles; |
#endif /* RAW_RANGE */ |
} else { |
printf("\nABORT: write out of registers\n"); |
cont_run = 0; |
421,7 → 410,6
static inline int fetch() |
{ |
struct mem_entry *entry; |
debug(5, "fetch()\n"); |
|
/* Update the pc for pending exceptions, or get physical pc */ |
if (!pending.valid) |
457,16 → 445,69
/* This code actually updates the PC value. */ |
static inline void update_pc () |
{ |
delay_insn = next_delay_insn; |
pcprev = pc; /* Store value for later */ |
pc = pcnext; |
pcnext = delay_insn ? pcdelay : pcnext + 4; |
} |
|
static inline void analysis () |
static inline void analysis (struct iqueue_entry *current) |
{ |
if (config.cpu.dependstats) { |
/* Dynamic, dependency stats. */ |
adddstats(icomplet[0].insn_index, current->insn_index, 1, check_depend()); |
|
/* Dynamic, functional units stats. */ |
addfstats(icomplet[0].func_unit, current->func_unit, 1, check_depend()); |
|
/* Dynamic, single stats. */ |
addsstats(current->insn_index, 1); |
} |
|
if (config.cpu.superscalar) { |
if ((current->func_unit == it_branch) || (current->func_unit == it_jump)) |
storecycles += 0; |
|
if (current->func_unit == it_store) |
storecycles += 1; |
|
if (current->func_unit == it_load) |
loadcycles += 1; |
#if 0 |
if ((icomplet[0].func_unit == it_load) && check_depend()) |
loadcycles++; |
#endif |
|
/* Pseudo multiple issue benchmark */ |
if ((multissue[current->func_unit] < 1) || (check_depend()) |
|| (issued_per_cycle < 1)) { |
int i; |
for (i = 0; i < 20; i++) |
multissue[i] = 2; |
issued_per_cycle = 2; |
supercycles++; |
if (check_depend()) |
hazardwait++; |
multissue[it_unknown] = 2; |
multissue[it_shift] = 2; |
multissue[it_compare] = 1; |
multissue[it_branch] = 1; |
multissue[it_jump] = 1; |
multissue[it_extend] = 2; |
multissue[it_nop] = 2; |
multissue[it_move] = 2; |
multissue[it_movimm] = 2; |
multissue[it_arith] = 2; |
multissue[it_store] = 2; |
multissue[it_load] = 2; |
} |
multissue[current->func_unit]--; |
issued_per_cycle--; |
} |
|
if (config.cpu.dependstats) |
/* Instruction waits in completition buffer until retired. */ |
memcpy (&icomplet[0], &iqueue[0], sizeof (struct iqueue_entry)); |
memcpy (&icomplet[0], current, sizeof (struct iqueue_entry)); |
|
if (config.sim.history) { |
int i; |
538,7 → 579,7
} |
|
/* Outputs dissasembled instruction */ |
void dump_exe_log (const char *disasm) |
void dump_exe_log () |
{ |
unsigned long i = iqueue[0].insn_addr; |
|
566,7 → 607,9
case EXE_LOG_SIMPLE: |
case EXE_LOG_SOFTWARE: |
{ |
extern char *disassembled; |
int labels = 0; |
disassemble_index (iqueue[0].insn, iqueue[0].insn_index); |
if (verify_memoryarea(i)) { |
struct label_entry *entry; |
entry = get_label(i); |
595,26 → 638,12
} |
|
fprintf (runtime.sim.fexe_log, "%.8lx ", i); |
fprintf (runtime.sim.fexe_log, "%s\n", disasm); |
fprintf (runtime.sim.fexe_log, "%s\n", disassembled); |
} |
} |
} |
} |
|
static char exe_log_temp[100]; |
|
/* Execution logger. Dissasemble an instruction and calls executed log. */ |
inline void dump_exe_log_dis () |
{ |
if (index >= 0) { |
extern char *disassembled; |
disassemble_index (iqueue[0].insn, iqueue[0].insn_index); |
sprintf (exe_log_temp, "%s", disassembled); |
} else |
sprintf (exe_log_temp, "<invalid>"); |
dump_exe_log (exe_log_temp); |
} |
|
#if 0 |
void print_time (int cycles, char *output) |
{ |
628,6 → 657,7
} |
#endif |
|
/* Dump registers - 'r' or 't' command */ |
void dumpreg() |
{ |
int i; |
654,6 → 684,7
printf("flag: %u\n", flag); |
} |
|
/* Generated/built in decoding/executing function */ |
static inline void decode_execute (struct iqueue_entry *current); |
|
/* Wrapper around real decode_execute function -- some statistics here only */ |
666,12 → 697,9
#error HAS_EXECUTION has to be defined in order to execute programs. |
#endif |
|
IFF (config.cpu.dependstats) current->func_unit = it_unknown; |
|
if(config.debug.enabled && CheckDebugUnit(DebugInstructionFetch, pc_phy)) |
breakpoint++; |
|
cur = current; /* globals; needed by eval/set_operand */ |
decode_execute (current); |
|
/* Check for range exception */ |
678,60 → 706,6
if (testsprbits (SPR_SR, SPR_SR_OVE) && testsprbits (SPR_SR, SPR_SR_OV)) |
except_handle (EXCEPT_RANGE, mfspr(SPR_EEAR_BASE)); |
|
if (config.cpu.dependstats) { |
iqueue[0].insn_index = current->insn_index; |
/* Dynamic, dependency stats. */ |
adddstats(icomplet[0].insn_index, iqueue[0].insn_index, 1, check_depend()); |
|
/* Dynamic, functional units stats. */ |
addfstats(icomplet[0].func_unit, iqueue[0].func_unit, 1, check_depend()); |
|
/* Dynamic, single stats. */ |
addsstats(iqueue[0].insn_index, 1); |
} |
|
if (config.cpu.superscalar) { |
if ((cur->func_unit == it_branch) || (cur->func_unit == it_jump)) |
storecycles += 0; |
|
if (cur->func_unit == it_store) |
storecycles += 1; |
|
if (cur->func_unit == it_load) |
loadcycles += 1; |
#if 0 |
if ((icomplet[0].func_unit == it_load) && check_depend()) |
loadcycles++; |
#endif |
|
/* Pseudo multiple issue benchmark */ |
if ((multissue[cur->func_unit] < 1) || (check_depend()) |
|| (issued_per_cycle < 1)) { |
int i; |
for (i = 0; i < 20; i++) |
multissue[i] = 2; |
issued_per_cycle = 2; |
supercycles++; |
if (check_depend()) |
hazardwait++; |
multissue[it_unknown] = 2; |
multissue[it_shift] = 2; |
multissue[it_compare] = 1; |
multissue[it_branch] = 1; |
multissue[it_jump] = 1; |
multissue[it_extend] = 2; |
multissue[it_nop] = 2; |
multissue[it_move] = 2; |
multissue[it_movimm] = 2; |
multissue[it_arith] = 2; |
multissue[it_store] = 2; |
multissue[it_load] = 2; |
} |
multissue[cur->func_unit]--; |
issued_per_cycle--; |
} |
delay_insn = next_delay_insn; |
|
if(breakpoint) |
except_handle(EXCEPT_TRAP, mfspr(SPR_EEAR_BASE)); |
} |
772,6 → 746,7
except_handle(EXCEPT_RESET, 0); |
} |
|
/* Simulates one CPU clock cycle */ |
inline int cpu_clock () |
{ |
if(fetch()) { |
781,12 → 756,16
} |
decode_execute_wrapper (&iqueue[0]); |
update_pc(); |
analysis(); |
if (config.sim.exe_log) dump_exe_log_dis(); |
analysis(&iqueue[0]); |
if (config.sim.exe_log) dump_exe_log(); |
return 0; |
} |
|
/* If decoding cannot be found, call this function */ |
void l_invalid () { |
/* It would be hard to handle this case for statistics; we skip it |
since it should not occur anyway: |
IFF (config.cpu.dependstats) current->func_unit = it_unknown; */ |
except_handle(EXCEPT_ILLEGAL, iqueue[0].insn_addr); |
} |
|
797,7 → 776,7
|
|
#if SIMPLE_EXECUTION |
/* Address calculation changed by CZ on 27/05/01 */ |
/* Simple and rather slow decoding function based on built automata. */ |
static inline void decode_execute (struct iqueue_entry *current) |
{ |
int insn_index; |
807,8 → 786,8
if (insn_index < 0) |
l_invalid(); |
else { |
op = &cur->op[0]; |
eval_operands (cur->insn, insn_index, &breakpoint); |
op = ¤t->op[0]; |
eval_operands (current->insn, insn_index, &breakpoint); |
or32_opcodes[insn_index].exec(); |
} |
} |
/trunk/or1ksim/cpu/or32/insnset.c
22,7 → 22,7
signed long temp1; |
signed char temp4; |
|
IFF (config.cpu.dependstats) cur->func_unit = it_arith; |
IFF (config.cpu.dependstats) current->func_unit = it_arith; |
temp1 = (signed long)eval_operand32(2, &breakpoint)+(signed long)eval_operand32(1, &breakpoint); |
set_operand32(0, temp1, &breakpoint); |
set_ov_flag (temp1); |
37,7 → 37,7
} |
INSTRUCTION (l_sw) { |
int old_cyc = 0; |
IFF (config.cpu.dependstats) cur->func_unit = it_store; |
IFF (config.cpu.dependstats) current->func_unit = it_store; |
IFF (config.cpu.sbuf_len) old_cyc = mem_cycles; |
set_operand32(0, eval_operand32(1, &breakpoint), &breakpoint); |
if (config.cpu.sbuf_len) { |
48,7 → 48,7
} |
INSTRUCTION (l_sb) { |
int old_cyc = 0; |
IFF (config.cpu.dependstats) cur->func_unit = it_store; |
IFF (config.cpu.dependstats) current->func_unit = it_store; |
IFF (config.cpu.sbuf_len) old_cyc = mem_cycles; |
set_operand8(0, eval_operand32(1, &breakpoint), &breakpoint); |
if (config.cpu.sbuf_len) { |
59,7 → 59,7
} |
INSTRUCTION (l_sh) { |
int old_cyc = 0; |
IFF (config.cpu.dependstats) cur->func_unit = it_store; |
IFF (config.cpu.dependstats) current->func_unit = it_store; |
IFF (config.cpu.sbuf_len) old_cyc = mem_cycles; |
set_operand16(0, eval_operand32(1, &breakpoint), &breakpoint); |
if (config.cpu.sbuf_len) { |
70,7 → 70,7
} |
INSTRUCTION (l_lwz) { |
unsigned long val; |
IFF (config.cpu.dependstats) cur->func_unit = it_load; |
IFF (config.cpu.dependstats) current->func_unit = it_load; |
if (config.cpu.sbuf_len) sbuf_load (); |
val = eval_operand32(1, &breakpoint); |
/* If eval operand produced exception don't set anything */ |
79,7 → 79,7
} |
INSTRUCTION (l_lbs) { |
signed char val; |
IFF (config.cpu.dependstats) cur->func_unit = it_load; |
IFF (config.cpu.dependstats) current->func_unit = it_load; |
if (config.cpu.sbuf_len) sbuf_load (); |
val = eval_operand8(1, &breakpoint); |
/* If eval opreand produced exception don't set anything */ |
88,7 → 88,7
} |
INSTRUCTION (l_lbz) { |
unsigned char val; |
IFF (config.cpu.dependstats) cur->func_unit = it_load; |
IFF (config.cpu.dependstats) current->func_unit = it_load; |
if (config.cpu.sbuf_len) sbuf_load (); |
val = eval_operand8(1, &breakpoint); |
/* If eval opreand produced exception don't set anything */ |
97,7 → 97,7
} |
INSTRUCTION (l_lhs) { |
signed short val; |
IFF (config.cpu.dependstats) cur->func_unit = it_load; |
IFF (config.cpu.dependstats) current->func_unit = it_load; |
if (config.cpu.sbuf_len) sbuf_load (); |
val = eval_operand16(1, &breakpoint); |
/* If eval opreand produced exception don't set anything */ |
106,7 → 106,7
} |
INSTRUCTION (l_lhz) { |
unsigned short val; |
IFF (config.cpu.dependstats) cur->func_unit = it_load; |
IFF (config.cpu.dependstats) current->func_unit = it_load; |
if (config.cpu.sbuf_len) sbuf_load (); |
val = eval_operand16(1, &breakpoint); |
/* If eval opreand produced exception don't set anything */ |
114,12 → 114,12
set_operand32(0, val, &breakpoint); |
} |
INSTRUCTION (l_movhi) { |
IFF (config.cpu.dependstats) cur->func_unit = it_movimm; |
IFF (config.cpu.dependstats) current->func_unit = it_movimm; |
set_operand32(0, eval_operand32(1, &breakpoint) << 16, &breakpoint); |
} |
INSTRUCTION (l_and) { |
unsigned long temp1; |
IFF (config.cpu.dependstats) cur->func_unit = it_arith; |
IFF (config.cpu.dependstats) current->func_unit = it_arith; |
set_operand32(0, temp1 = set_ov_flag (eval_operand32(1, &breakpoint) & (unsigned)eval_operand32(2, &breakpoint)), &breakpoint); |
if (ARITH_SET_FLAG) { |
flag = temp1 == 0; |
127,15 → 127,15
} |
} |
INSTRUCTION (l_or) { |
IFF (config.cpu.dependstats) cur->func_unit = it_arith; |
IFF (config.cpu.dependstats) current->func_unit = it_arith; |
set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) | (unsigned)eval_operand32(2, &breakpoint)), &breakpoint); |
} |
INSTRUCTION (l_xor) { |
IFF (config.cpu.dependstats) cur->func_unit = it_arith; |
IFF (config.cpu.dependstats) current->func_unit = it_arith; |
set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) ^ (signed)eval_operand32(2, &breakpoint)), &breakpoint); |
} |
INSTRUCTION (l_sub) { |
IFF (config.cpu.dependstats) cur->func_unit = it_arith; |
IFF (config.cpu.dependstats) current->func_unit = it_arith; |
set_operand32(0, set_ov_flag ((signed long)eval_operand32(1, &breakpoint) - (signed long)eval_operand32(2, &breakpoint)), &breakpoint); |
} |
/*int mcount = 0;*/ |
142,7 → 142,7
INSTRUCTION (l_mul) { |
signed long temp3, temp2, temp1; |
|
IFF (config.cpu.dependstats) cur->func_unit = it_arith; |
IFF (config.cpu.dependstats) current->func_unit = it_arith; |
set_operand32(0, set_ov_flag ((signed long)eval_operand32(1, &breakpoint) * (signed long)eval_operand32(2, &breakpoint)), &breakpoint); |
/*if (!(mcount++ & 1023)) { |
printf ("[%i]\n",mcount); |
151,7 → 151,7
INSTRUCTION (l_div) { |
signed long temp3, temp2, temp1; |
|
IFF (config.cpu.dependstats) cur->func_unit = it_arith; |
IFF (config.cpu.dependstats) current->func_unit = it_arith; |
temp3 = eval_operand32(2, &breakpoint); |
temp2 = eval_operand32(1, &breakpoint); |
if (temp3) |
165,7 → 165,7
INSTRUCTION (l_divu) { |
unsigned long temp3, temp2, temp1; |
|
IFF (config.cpu.dependstats) cur->func_unit = it_arith; |
IFF (config.cpu.dependstats) current->func_unit = it_arith; |
temp3 = eval_operand32(2, &breakpoint); |
temp2 = eval_operand32(1, &breakpoint); |
temp1 = temp2 / temp3; |
174,7 → 174,7
} |
INSTRUCTION (l_sll) { |
int sign = 1; |
IFF (config.cpu.dependstats) cur->func_unit = it_shift; |
IFF (config.cpu.dependstats) current->func_unit = it_shift; |
if ((signed)eval_operand32(1, &breakpoint) < 0) |
sign = -1; |
/* cycles += 2; */ |
182,7 → 182,7
} |
INSTRUCTION (l_sra) { |
unsigned long sign = 0; |
IFF (config.cpu.dependstats) cur->func_unit = it_shift; |
IFF (config.cpu.dependstats) current->func_unit = it_shift; |
|
if ((signed)eval_operand32(1, &breakpoint) < 0) |
sign = -1; |
190,7 → 190,7
set_operand32(0, set_ov_flag ((signed)eval_operand32(1, &breakpoint) >> eval_operand32(2, &breakpoint)), &breakpoint); |
} |
INSTRUCTION (l_srl) { |
IFF (config.cpu.dependstats) cur->func_unit = it_shift; |
IFF (config.cpu.dependstats) current->func_unit = it_shift; |
/* cycles += 2; */ |
set_operand32(0, set_ov_flag (eval_operand32(1, &breakpoint) >> eval_operand32(2, &breakpoint)), &breakpoint); |
} |
197,9 → 197,9
INSTRUCTION (l_bf) { |
if (config.bpb.enabled) { |
int fwd = (eval_operand32(0, &breakpoint) >= pc) ? 1 : 0; |
IFF (config.cpu.dependstats) cur->func_unit = it_branch; |
IFF (config.cpu.dependstats) current->func_unit = it_branch; |
mstats.bf[flag][fwd]++; |
bpb_update(cur->insn_addr, flag); |
bpb_update(current->insn_addr, flag); |
} |
if (flag) { |
pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; |
212,9 → 212,9
INSTRUCTION (l_bnf) { |
if (config.bpb.enabled) { |
int fwd = (eval_operand32(0, &breakpoint) >= pc) ? 1 : 0; |
IFF (config.cpu.dependstats) cur->func_unit = it_branch; |
IFF (config.cpu.dependstats) current->func_unit = it_branch; |
mstats.bnf[!flag][fwd]++; |
bpb_update(cur->insn_addr, flag == 0); |
bpb_update(current->insn_addr, flag == 0); |
} |
if (flag == 0) { |
pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; |
226,13 → 226,13
} |
INSTRUCTION (l_j) { |
pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; |
IFF (config.cpu.dependstats) cur->func_unit = it_jump; |
IFF (config.cpu.dependstats) current->func_unit = it_jump; |
next_delay_insn = 1; |
} |
INSTRUCTION (l_jal) { |
pcdelay = pc + (signed)eval_operand32(0, &breakpoint) * 4; |
|
IFF (config.cpu.dependstats) cur->func_unit = it_jump; |
IFF (config.cpu.dependstats) current->func_unit = it_jump; |
set_reg32(LINK_REGNO, pc + 8); |
next_delay_insn = 1; |
if (config.sim.profile) { |
245,13 → 245,13
} |
} |
INSTRUCTION (l_jalr) { |
IFF (config.cpu.dependstats) cur->func_unit = it_jump; |
IFF (config.cpu.dependstats) current->func_unit = it_jump; |
pcdelay = eval_operand32(0, &breakpoint); |
set_reg32(LINK_REGNO, pc + 8); |
next_delay_insn = 1; |
} |
INSTRUCTION (l_jr) { |
IFF (config.cpu.dependstats) cur->func_unit = it_jump; |
IFF (config.cpu.dependstats) current->func_unit = it_jump; |
pcdelay = eval_operand32(0, &breakpoint); |
next_delay_insn = 1; |
if (config.sim.profile) |
258,7 → 258,7
fprintf (runtime.sim.fprof, "-%08X %08X\n", cycles, pcdelay); |
} |
INSTRUCTION (l_rfe) { |
IFF (config.cpu.dependstats) cur->func_unit = it_exception; |
IFF (config.cpu.dependstats) current->func_unit = it_exception; |
pcnext = mfspr(SPR_EPCR_BASE); |
mtspr(SPR_SR, mfspr(SPR_ESR_BASE)); |
} |
265,7 → 265,7
INSTRUCTION (l_nop) { |
unsigned long stackaddr; |
int k = eval_operand32(0, &breakpoint); |
IFF (config.cpu.dependstats) cur->func_unit = it_nop; |
IFF (config.cpu.dependstats) current->func_unit = it_nop; |
switch (k) { |
case NOP_NOP: |
break; |
290,88 → 290,88
} |
} |
INSTRUCTION (l_sfeq) { |
IFF (config.cpu.dependstats) cur->func_unit = it_compare; |
IFF (config.cpu.dependstats) current->func_unit = it_compare; |
flag = eval_operand32(0, &breakpoint) == eval_operand32(1, &breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
INSTRUCTION (l_sfne) { |
IFF (config.cpu.dependstats) cur->func_unit = it_compare; |
IFF (config.cpu.dependstats) current->func_unit = it_compare; |
flag = eval_operand32(0, &breakpoint) != eval_operand32(1, &breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
INSTRUCTION (l_sfgts) { |
IFF (config.cpu.dependstats) cur->func_unit = it_compare; |
IFF (config.cpu.dependstats) current->func_unit = it_compare; |
flag = (signed)eval_operand32(0, &breakpoint) > (signed)eval_operand32(1, &breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
INSTRUCTION (l_sfges) { |
IFF (config.cpu.dependstats) cur->func_unit = it_compare; |
IFF (config.cpu.dependstats) current->func_unit = it_compare; |
flag = (signed)eval_operand32(0, &breakpoint) >= (signed)eval_operand32(1, &breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
INSTRUCTION (l_sflts) { |
IFF (config.cpu.dependstats) cur->func_unit = it_compare; |
IFF (config.cpu.dependstats) current->func_unit = it_compare; |
flag = (signed)eval_operand32(0, &breakpoint) < (signed)eval_operand32(1, &breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
INSTRUCTION (l_sfles) { |
IFF (config.cpu.dependstats) cur->func_unit = it_compare; |
IFF (config.cpu.dependstats) current->func_unit = it_compare; |
flag = (signed)eval_operand32(0, &breakpoint) <= (signed)eval_operand32(1, &breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
INSTRUCTION (l_sfgtu) { |
IFF (config.cpu.dependstats) cur->func_unit = it_compare; |
IFF (config.cpu.dependstats) current->func_unit = it_compare; |
flag = (unsigned)eval_operand32(0, &breakpoint) > (unsigned)eval_operand32(1, &breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
INSTRUCTION (l_sfgeu) { |
IFF (config.cpu.dependstats) cur->func_unit = it_compare; |
IFF (config.cpu.dependstats) current->func_unit = it_compare; |
flag = (unsigned)eval_operand32(0, &breakpoint) >= (unsigned) eval_operand32(1, &breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
INSTRUCTION (l_sfltu) { |
IFF (config.cpu.dependstats) cur->func_unit = it_compare; |
IFF (config.cpu.dependstats) current->func_unit = it_compare; |
flag = (unsigned)eval_operand32(0, &breakpoint) < (unsigned)eval_operand32(1, &breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
INSTRUCTION (l_sfleu) { |
IFF (config.cpu.dependstats) cur->func_unit = it_compare; |
IFF (config.cpu.dependstats) current->func_unit = it_compare; |
flag = (unsigned)eval_operand32(0, &breakpoint) <= (unsigned)eval_operand32(1, &breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
INSTRUCTION (l_extbs) { |
unsigned char x; |
IFF (config.cpu.dependstats) cur->func_unit = it_move; |
IFF (config.cpu.dependstats) current->func_unit = it_move; |
x = eval_operand32(1, &breakpoint); |
set_operand32(0, (signed long)x, &breakpoint); |
} |
INSTRUCTION (l_extbz) { |
unsigned char x; |
IFF (config.cpu.dependstats) cur->func_unit = it_move; |
IFF (config.cpu.dependstats) current->func_unit = it_move; |
x = eval_operand32(1, &breakpoint); |
set_operand32(0, (unsigned long)x, &breakpoint); |
} |
INSTRUCTION (l_exths) { |
unsigned short x; |
IFF (config.cpu.dependstats) cur->func_unit = it_move; |
IFF (config.cpu.dependstats) current->func_unit = it_move; |
x = eval_operand32(1, &breakpoint); |
set_operand32(0, (signed long)x, &breakpoint); |
} |
INSTRUCTION (l_exthz) { |
unsigned short x; |
IFF (config.cpu.dependstats) cur->func_unit = it_move; |
IFF (config.cpu.dependstats) current->func_unit = it_move; |
x = eval_operand32(1, &breakpoint); |
set_operand32(0, (unsigned long)x, &breakpoint); |
} |
INSTRUCTION (l_extws) { |
unsigned int x; |
IFF (config.cpu.dependstats) cur->func_unit = it_move; |
IFF (config.cpu.dependstats) current->func_unit = it_move; |
x = eval_operand32(1, &breakpoint); |
set_operand32(0, (signed long)x, &breakpoint); |
} |
INSTRUCTION (l_extwz) { |
unsigned int x; |
IFF (config.cpu.dependstats) cur->func_unit = it_move; |
IFF (config.cpu.dependstats) current->func_unit = it_move; |
x = eval_operand32(1, &breakpoint); |
set_operand32(0, (unsigned long)x, &breakpoint); |
} |
383,7 → 383,7
fprintf(runtime.sim.fspr_log, "Write to SPR : [%08lX] <- [%08lX]\n", regno, value); |
} |
|
IFF (config.cpu.dependstats) cur->func_unit = it_move; |
IFF (config.cpu.dependstats) current->func_unit = it_move; |
if (mfspr(SPR_SR) & SPR_SR_SM) |
mtspr(regno, value); |
else { |
399,7 → 399,7
fprintf(runtime.sim.fspr_log, "Read from SPR : [%08lX] -> [%08lX]\n", regno, value); |
} |
|
IFF (config.cpu.dependstats) cur->func_unit = it_move; |
IFF (config.cpu.dependstats) current->func_unit = it_move; |
if (mfspr(SPR_SR) & SPR_SR_SM) |
set_operand32(0, value, &breakpoint); |
else { |
419,7 → 419,7
sprword lo, hi; |
LONGEST l; |
long x, y; |
IFF (config.cpu.dependstats) cur->func_unit = it_mac; |
IFF (config.cpu.dependstats) current->func_unit = it_mac; |
lo = mfspr (SPR_MACLO); |
hi = mfspr (SPR_MACHI); |
x = eval_operand32(0, &breakpoint); |
439,7 → 439,7
sprword lo, hi; |
LONGEST l; |
long x, y; |
IFF (config.cpu.dependstats) cur->func_unit = it_mac; |
IFF (config.cpu.dependstats) current->func_unit = it_mac; |
lo = mfspr (SPR_MACLO); |
hi = mfspr (SPR_MACHI); |
x = eval_operand32(0, &breakpoint); |
458,7 → 458,7
INSTRUCTION (l_macrc) { |
sprword lo, hi; |
LONGEST l; |
IFF (config.cpu.dependstats) cur->func_unit = it_mac; |
IFF (config.cpu.dependstats) current->func_unit = it_mac; |
/* No need for synchronization here -- all MAC instructions are 1 cycle long. */ |
lo = mfspr (SPR_MACLO); |
hi = mfspr (SPR_MACHI); |
470,13 → 470,13
mtspr (SPR_MACHI, 0); |
} |
INSTRUCTION (l_cmov) { |
IFF (config.cpu.dependstats) cur->func_unit = it_move; |
IFF (config.cpu.dependstats) current->func_unit = it_move; |
set_operand32(0, flag ? eval_operand32(1, &breakpoint) : eval_operand32(2, &breakpoint), &breakpoint); |
} |
INSTRUCTION (l_cust1) { |
/*int destr = cur->insn >> 21; |
int src1r = cur->insn >> 15; |
int src2r = cur->insn >> 9;*/ |
/*int destr = current->insn >> 21; |
int src1r = current->insn >> 15; |
int src2r = current->insn >> 9;*/ |
} |
INSTRUCTION (l_cust2) { |
} |
/trunk/or1ksim/cpu/or32/generate.c
61,8 → 61,14
#endif |
} |
|
/* Whether this instruction stores something in register */ |
static int write_to_reg = 0; |
|
static int olevel; |
|
/* Following functions recursivelly searches for substrings eval_operand and |
set_operand (see functions with the same name in execute.c) and replaces |
them with optimized code. */ |
char *replace_operands (FILE *fo, char *str) { |
int replace = 0; |
if (*str == '}') {olevel--;} |
83,7 → 89,7
fprintf (fo, "eval_mem%i (%c", width, 'a' + oper); |
} else { |
if (op[oper] & OPTYPE_REG) { |
fprintf (fo, "eval_reg%i (%c", width, 'a' + oper); |
fprintf (fo, "(reg[%c]", 'a' + oper); |
} else { |
fprintf (fo, "(%c", 'a' + oper); |
} |
93,7 → 99,8
if (op[oper] & OPTYPE_DIS) { |
fprintf (fo, "set_mem%i(%c,", width, 'a' + oper); |
} else if (op[oper] & OPTYPE_REG) { |
fprintf (fo, "set_reg%i(%c,",width, 'a' + oper); |
fprintf (fo, "reg[%c] = (", 'a' + oper); |
write_to_reg = 1; |
} else { |
fprintf (stderr, "Invalid operand type.\n"); |
exit (1); |
109,6 → 116,7
return str; |
} |
|
/* Generates a execute sequence for one instruction */ |
int output_function (FILE *fo, const char *func_name, int level) |
{ |
FILE *fi; |
196,7 → 204,11
} else |
{ |
if (dis && (opd->type & OPTYPE_REG)) { |
SHIFT; fprintf (fo, "op[%i] = %c = data + eval_reg32 (tmp);\n", no, 'a' + no); |
if (MAX_GPRS == (1 << nbits)) { |
SHIFT; fprintf (fo, "op[%i] = %c = data + reg [tmp];\n", no, 'a' + no); |
}else { |
SHIFT; fprintf (fo, "op[%i] = %c = data + eval_reg32 (tmp);\n", no, 'a' + no); |
} |
} else { |
SHIFT; fprintf (fo, "op[%i] = %c = tmp;\n", no, 'a' + no); |
} |
216,6 → 228,7
SHIFT; fprintf (fo, "num_op = %i;\n", no); |
} |
|
/* Generates decode and execute for one instruction instance */ |
int output_call (FILE *fo, int index, int level) |
{ |
int i; |
226,35 → 239,41
SHIFT; fprintf (fo, "unsigned long data, tmp;\n"); |
SHIFT; fprintf (fo, "unsigned long a, b, c; /* operands */\n"); |
} |
write_to_reg = 0; |
if (index >= 0) { |
SHIFT; fprintf (fo, "insn_index = %i; /* \"%s\" */\n", index, insn_name (index)); |
gen_eval_operands (fo, index, level); |
} else { |
SHIFT; fprintf (fo, "/* insn_index = -1 by default */\n"); |
SHIFT; fprintf (fo, "insn_index = -1;\n"); |
} |
SHIFT; |
if (index < 0) output_function (fo, "l_invalid", level); |
else output_function (fo, or32_opcodes[index].function_name, level); |
printf ("\n"); |
fprintf (fo, "\n"); |
for (i = 0; i < num_op; i++) |
if (op[i] & OPTYPE_DST) { |
SHIFT; fprintf (fo, "IFF (config.cpu.dependstats) op[%i + MAX_OPERANDS] |= OPTYPE_DST;\n", i); |
} |
if (write_to_reg) { |
SHIFT; fprintf (fo, "reg[0] = 0; /* Repair in case we changed it */\n", i); |
} |
level--; |
SHIFT; fprintf (fo, "}"); |
return 0; |
} |
|
/* Generates .c file header */ |
static int generate_header (FILE *fo) |
{ |
fprintf (fo, "/* This file was automatically generated by generate (see cpu/or32/generate.c) */\n\n"); |
fprintf (fo, "static inline void decode_execute (struct iqueue_entry *current)\n{\n"); |
fprintf (fo, " unsigned long insn = current->insn;\n"); |
fprintf (fo, " int insn_index = -1;\n"); |
fprintf (fo, " op = &cur->op[0];\n"); |
fprintf (fo, " int insn_index;\n"); |
fprintf (fo, " op = ¤t->op[0];\n"); |
return 0; |
} |
|
/* Generates .c file footer */ |
int generate_footer (FILE *fo) |
{ |
fprintf (fo, " current->insn_index = insn_index;\n"); |
349,3 → 368,4
destruct_automata (); |
return 0; |
} |
|
/trunk/or1ksim/cpu/common/stats.c
266,8 → 266,10
|
case 5: |
printf("stats 5: Raw register usage over time\n"); |
for(i = 0; (i < config.cpu.raw_range); i++) |
#if RAW_RANGE_STATS |
for(i = 0; (i < MAX_RANGE); i++) |
printf(" Register set and reused in %d. cycle: %d cases\n", i, raw_stats.range[i]); |
#endif |
break; |
case 6: |
if (config.cpu.sbuf_len) { |
/trunk/or1ksim/peripheral/16450.c
379,6 → 379,7
uarts[i].istat.break_set = 0; |
uarts[i].istat.timeout_count = 0; |
uarts[i].istat.thre_int = 1; /* FIFO is empty at start */ |
uarts[i].slowdown = UART_FGETC_SLOWDOWN; |
|
uarts[i].regs.lcr = UART_LCR_RESET; |
uarts[i].vapi.cur_break = uarts[i].vapi.cur_break_cnt = uarts[i].vapi.next_break = 0; |
484,10 → 485,12
} else { |
if (!config.uarts[i].vapi_id) { |
if(uarts[i].istat.rxser_full == 0) { |
if((retval = fgetc(uarts[i].rxfs)) != EOF) { |
if (uarts[i].slowdown) |
uarts[i].slowdown--; |
else if((retval = fgetc(uarts[i].rxfs)) != EOF) { |
uarts[i].iregs.rxser = (char)retval; |
uarts[i].istat.rxser_full = 1; |
} |
} else uarts[i].slowdown = UART_FGETC_SLOWDOWN; |
} |
} else { /* VAPI */ |
int received = 0; |
/trunk/or1ksim/peripheral/16450.h
28,6 → 28,7
#define UART_VAPI_BUF_LEN 128 /* Size of VAPI command buffer - VAPI should not send more |
that this amout of char before requesting something back */ |
#define UART_CLOCK_DIVIDER 16 /* Uart clock divider */ |
#define UART_FGETC_SLOWDOWN 100 /* fgetc slowdown factor */ |
|
/* Registers */ |
|
92,6 → 93,9
|
/* Length of FIFO, 16 for 16550, 1 for 16450 */ |
int fifo_len; |
|
/* fgetc slowdown */ |
int slowdown; |
|
/* Required by standard file streams */ |
FILE * rxfs; |
/trunk/or1ksim/mmu/immu.c
30,7 → 30,7
|
/* Insn MMU */ |
|
inline unsigned long immu_simulate_tlb(unsigned long virtaddr) |
static inline unsigned long immu_simulate_tlb(unsigned long virtaddr) |
{ |
int set, way = -1; |
int i; |
/trunk/or1ksim/toplevel.c
57,7 → 57,7
#include "mprofiler.h" |
|
/* CVS revision number. */ |
const char rcsrev[] = "$Revision: 1.76 $"; |
const char rcsrev[] = "$Revision: 1.77 $"; |
|
/* Continuos run versus single step tracing switch. */ |
int cont_run; |
671,9 → 671,9
} else |
#endif /* !FAST_SIM */ |
printf("%s: Unknown command.\n", linestr); |
|
|
/* MM: 'run -1' means endless execution. */ |
while(cont_run != 0) { |
while(cont_run) { |
extern int mem_cycles; |
|
IFF (config.debug.enabled) { |
/trunk/or1ksim/sim-config.c
125,7 → 125,6
config.sim.history = 0; |
config.cpu.hazards = 0; |
config.cpu.dependstats = 0; |
config.cpu.raw_range = 0; |
config.cpu.sbuf_len = 0; |
config.cpu.upr = SPR_UPR_UP | SPR_UPR_DCP | SPR_UPR_ICP | SPR_UPR_DMP |
| SPR_UPR_IMP | SPR_UPR_OB32P | SPR_UPR_DUP | SPR_UPR_PICP |
391,7 → 390,6
void memory_log (); |
void memory_delayr (); |
void memory_delayw (); |
void cpu_raw_range (); |
void cpu_sbuf_len (); |
void eth_nethernets (); |
void eth_baseaddr (); |
525,7 → 523,6
{5, "hazards", "=%i", NULL, (void *)(&config.cpu.hazards), 0}, |
{5, "superscalar", "=%i", NULL, (void *)(&config.cpu.superscalar), 0}, |
{5, "dependstats", "=%i", NULL, (void *)(&config.cpu.dependstats), 0}, |
{5, "raw_range", "=%i", cpu_raw_range, (void *)(&config.cpu.raw_range), 0}, |
{5, "sbuf_len", "=%i", cpu_sbuf_len, (void *)(&config.cpu.sbuf_len), 0}, |
|
{6, "debug", "=%i", NULL, (void *)(&config.sim.debug), 0}, |
850,16 → 847,6
ERROR("invalid device number."); |
} |
|
void cpu_raw_range () { |
if (config.cpu.raw_range >= RAW_RANGE) { |
config.cpu.raw_range = RAW_RANGE - 1; |
WARNING("raw range too large; truncated."); |
} else if (config.cpu.raw_range < 0) { |
config.cpu.raw_range = 0; |
WARNING("raw range negative; disabled."); |
} |
} |
|
void cpu_sbuf_len () { |
if (config.cpu.sbuf_len >= MAX_SBUF_LEN) { |
config.cpu.sbuf_len = MAX_SBUF_LEN - 1; |
1408,9 → 1395,9
config.bpb.enabled, config.bpb.sbp_bnf_fwd, config.bpb.sbp_bf_fwd, config.bpb.btic, config.bpb.missdelay, config.bpb.hitdelay); |
|
fprintf (f, " cpu:{upr:0x%08x, ver:0x%04x, rev:0x%04x, superscalar:%i, hazards:%i, dependstats:%i,\n" |
" raw_range:%i, sr:0x%08x},\n", |
" sr:0x%08x},\n", |
config.cpu.upr, config.cpu.ver, config.cpu.rev, config.cpu.superscalar, config.cpu.hazards, config.cpu.dependstats, |
config.cpu.raw_range, config.cpu.sr); |
config.cpu.sr); |
|
fprintf (f, " sim:{debug:%i, verbose:%i, profile:%i, prof_fn:\"%s\", mprofile:%i, mprof_fn:\"%s\",\n", |
config.sim.debug, config.sim.verbose, config.sim.profile, config.sim.prof_fn, config.sim.mprofile, config.sim.mprof_fn); |