URL
https://opencores.org/ocsvn/or1k_old/or1k_old/trunk
Subversion Repositories or1k_old
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 559 to Rev 560
- ↔ Reverse comparison
Rev 559 → Rev 560
/trunk/or1ksim/cpu/or32/execute.c
105,10 → 105,40
/* Implementation specific. |
Get an actual value of a specific register. */ |
|
machword eval_reg(int regno) |
unsigned long evalsim_reg32(int regno) |
{ |
if (regno < MAX_GPRS) { |
if (config.cpu.raw_range) { |
return reg[regno]; |
} else { |
printf("\nABORT: read out of registers\n"); |
cont_run = 0; |
return 0; |
} |
} |
|
/* Implementation specific. |
Set a specific register with value. */ |
|
void setsim_reg32(int regno, unsigned long value) |
{ |
if (regno == 0) /* gpr0 is always zero */ |
value = 0; |
|
if (regno < MAX_GPRS) { |
reg[regno] = value; |
} else { |
printf("\nABORT: write out of registers\n"); |
cont_run = 0; |
} |
} |
|
/* Implementation specific. |
Get an actual value of a specific register. */ |
|
inline static unsigned long eval_reg32(int regno) |
{ |
if (regno < MAX_GPRS) { |
IFF(config.cpu.raw_range) { |
int delta = (cycles - raw_stats.reg[regno]); |
if (delta < config.cpu.raw_range) |
raw_stats.range[delta]++; |
125,7 → 155,7
/* Implementation specific. |
Set a specific register with value. */ |
|
void set_reg32(int regno, unsigned long value) |
inline static void set_reg32(int regno, unsigned long value) |
{ |
#if 0 |
if (strcmp(regstr, FRAME_REG) == 0) { |
138,12 → 168,10
printf("Old:%.8lx New:%.8lx\n", eval_reg(regmo), value); |
} |
#endif |
if (regno == 0) /* gpr0 is always zero */ |
value = 0; |
|
|
if (regno < MAX_GPRS) { |
reg[regno] = value; |
if (config.cpu.raw_range) |
IFF(config.cpu.raw_range) |
raw_stats.reg[regno] = cycles; |
} else { |
printf("\nABORT: write out of registers\n"); |
183,7 → 211,7
} |
else |
i++; |
|
|
/* We search all source operands - if we find confict => return 1 */ |
i = 0; |
while (!(next->op[i + MAX_OPERANDS] & OPTYPE_LAST)) |
216,6 → 244,7
unsigned long data = 0; |
int dis = 0; |
int no = 0; |
|
while (1) |
{ |
unsigned long tmp = 0, nbits = 0; |
242,7 → 271,7
} else |
{ |
if (dis && (opd->type & OPTYPE_REG)) |
op[no] = data + eval_reg (tmp); |
op[no] = data + eval_reg32 (tmp); |
else |
op[no] = tmp; |
op[no + MAX_OPERANDS] = opd->type | (dis ? OPTYPE_DIS : 0); |
260,21 → 289,23
/* Implementation specific. |
Evaluates source operand op_no. */ |
|
unsigned long eval_operand32 (int op_no, int *breakpoint) |
inline static unsigned long eval_operand32 (int op_no, int *breakpoint) |
{ |
debug (9, "%i %08X\n", op_no, op[op_no + MAX_OPERANDS]); |
if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) |
/* memory accesses are not cached */ |
return eval_mem32 (op[op_no], breakpoint); |
else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) |
return eval_reg (op[op_no]); |
else |
else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) { |
return eval_reg32 (op[op_no]); |
} else { |
return op[op_no]; |
} |
} |
|
/* Implementation specific. |
Evaluates source operand op_no. */ |
|
unsigned long eval_operand16 (int op_no, int *breakpoint) |
static unsigned long eval_operand16 (int op_no, int *breakpoint) |
{ |
debug (9, "%i %08X\n", op_no, op[op_no + MAX_OPERANDS]); |
if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) { |
292,7 → 323,7
/* Implementation specific. |
Evaluates source operand op_no. */ |
|
unsigned long eval_operand8 (int op_no, int *breakpoint) |
static unsigned long eval_operand8 (int op_no, int *breakpoint) |
{ |
debug (9, "%i %08X\n", op_no, op[op_no + MAX_OPERANDS]); |
if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) |
307,26 → 338,20
Set destination operand (register direct, register indirect |
(with displacement) with value. */ |
|
void set_operand32(int op_no, unsigned long value, int* breakpoint) |
inline static void set_operand32(int op_no, unsigned long value, int* breakpoint) |
{ |
/* Mark this as destination operand. */ |
op[op_no + MAX_OPERANDS] |= OPTYPE_DST; |
IFF (config.cpu.dependstats) op[op_no + MAX_OPERANDS] |= OPTYPE_DST; |
if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) { |
if (op[op_no] & 0x03) { |
except_handle (EXCEPT_ALIGN, op[op_no]); |
return; |
} |
set_mem32(op[op_no], value, breakpoint); |
} |
else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) { |
} else if (op[op_no + MAX_OPERANDS] & OPTYPE_REG) { |
set_reg32(op[op_no], value); |
/* TODO: OV incorrect */ |
value & 0x80000000 ? setsprbits (SPR_SR, SPR_SR_OV, 1) : setsprbits (SPR_SR, SPR_SR_OV, 0); |
} else { |
fprintf (stderr, "Invalid operand type.\n"); |
exit (1); |
} |
else |
{ |
fprintf (stderr, "Invalid operand type.\n"); |
exit (1); |
} |
} |
|
/* Implementation specific. |
336,7 → 361,7
void set_operand16(int op_no, unsigned long value, int* breakpoint) |
{ |
/* Mark this as destination operand. */ |
op[op_no + MAX_OPERANDS] |= OPTYPE_DST; |
op[op_no + MAX_OPERANDS] |= OPTYPE_DST; |
if (op[op_no + MAX_OPERANDS] & OPTYPE_DIS) { |
if (op[op_no] & 0x01) { |
except_handle (EXCEPT_ALIGN, op[op_no]); |
397,16 → 422,9
pc_phy &= ~0x03; |
|
/* Fetch instruction. */ |
{ |
unsigned int _insn; |
|
_insn = eval_insn (pc_phy, &breakpoint); |
iqueue[0].insn_addr = pc; |
iqueue[0].insn_addr = pc; |
iqueue[0].insn = eval_insn (pc_phy, &breakpoint);; |
|
iqueue[0].insn_index = insn_decode(_insn); |
iqueue[0].insn = _insn; |
} |
|
/* update_pc will be called after execution */ |
|
return 0; |
492,43 → 510,45
for(i = 0; i < MAX_GPRS; i++) { |
if (i % 4 == 0) |
printf("\n"); |
printf("GPR%.2u: %.8lx ", i, reg[i]); |
printf("GPR%.2u: %.8lx ", i, evalsim_reg32(i)); |
} |
printf("flag: %u\n", flag); |
} |
|
/* Address calculation changed by CZ on 27/05/01 */ |
inline void decode_execute(struct iqueue_entry *current) |
static inline void decode_execute(struct iqueue_entry *current) |
{ |
int insn_index; |
next_delay_insn = 0; |
breakpoint = 0; |
|
|
if(config.debug.enabled && CheckDebugUnit(DebugInstructionFetch, pc_phy)) |
breakpoint++; |
|
cur = current; |
IFF (config.cpu.dependstats) IFF (config.cpu.dependstats) cur->func_unit = it_unknown; |
op = &cur->op[0]; |
IFF (config.cpu.dependstats) current->func_unit = it_unknown; |
|
current->insn_index = insn_index = insn_decode(current->insn); |
|
/* printf("0x%04x: Executing \"%s\"\n",pc,cur->insn); */ |
|
#ifndef HAS_EXECUTION |
#error HAS_EXECUTION has to be defined in order to execute programs. |
#endif |
|
if (cur->insn_index < 0) |
cur = current; /* globals; needed by eval/set_operand */ |
|
if (insn_index < 0) |
l_invalid(); |
else |
{ |
eval_operands (cur->insn, cur->insn_index, &breakpoint); |
or32_opcodes[cur->insn_index].exec(); |
} |
|
else { |
op = &cur->op[0]; |
eval_operands (cur->insn, insn_index, &breakpoint); |
or32_opcodes[insn_index].exec(); |
} |
|
/* Check for range exception */ |
if (testsprbits (SPR_SR, SPR_SR_OVE) && testsprbits (SPR_SR, SPR_SR_OV)) |
except_handle (EXCEPT_RANGE, 0); |
|
if (config.cpu.dependstats) { |
iqueue[0].insn_index = insn_index; |
/* Dynamic, dependency stats. */ |
adddstats(icomplet[0].insn_index, iqueue[0].insn_index, 1, check_depend()); |
|
538,7 → 558,7
/* 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; |
555,8 → 575,7
|
/* Pseudo multiple issue benchmark */ |
if ((multissue[cur->func_unit] < 1) || (check_depend()) |
|| (issued_per_cycle < 1) |
) { |
|| (issued_per_cycle < 1)) { |
int i; |
for (i = 0; i < 20; i++) |
multissue[i] = 2; |
852,7 → 871,7
case NOP_NOP: |
break; |
case NOP_EXIT: |
printf("exit(%d)\n", eval_reg (3)); |
printf("exit(%d)\n", evalsim_reg32 (3)); |
if (config.debug.gdb_enabled) |
set_stall_state (1); |
else |
859,15 → 878,15
cont_run = 0; |
break; |
case NOP_PRINTF: |
stackaddr = eval_reg(4); |
simprintf(stackaddr, eval_reg(3)); |
stackaddr = evalsim_reg32(4); |
simprintf(stackaddr, evalsim_reg32(3)); |
debug(5, "simprintf %x\n", stackaddr); |
break; |
case NOP_REPORT: |
printf("report(0x%x);\n", eval_reg(3)); |
printf("report(0x%x);\n", evalsim_reg32(3)); |
default: |
if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST) |
printf("report %i (0x%x);\n", k - NOP_REPORT_FIRST, eval_reg(3)); |
printf("report %i (0x%x);\n", k - NOP_REPORT_FIRST, evalsim_reg(3)); |
break; |
} |
} |
/trunk/or1ksim/cpu/common/abstract.c
223,17 → 223,128
|
|
/* Check if access is to registered area of memory. */ |
struct dev_memarea *verify_memoryarea(unsigned long addr) |
inline struct dev_memarea *verify_memoryarea(unsigned long addr) |
{ |
struct dev_memarea *ptmp; |
|
/* Check list of registered devices. */ |
for(ptmp = dev_list; ptmp; ptmp = ptmp->next) |
if (ptmp->valid && ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask))) |
return cur_area = ptmp; |
/* Check cached value first */ |
if (cur_area && (addr & cur_area->addr_mask) == (cur_area->addr_compare & cur_area->addr_mask)) |
return cur_area; |
|
/* When mc is enabled, we must check valid also, otherwise we assume it is nonzero */ |
IFF (config.mc.enabled) { |
/* Check list of registered devices. */ |
for(ptmp = dev_list; ptmp; ptmp = ptmp->next) |
if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask) && ptmp->valid) |
return cur_area = ptmp; |
} else { |
/* Check list of registered devices. */ |
for(ptmp = dev_list; ptmp; ptmp = ptmp->next) |
if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask)) |
return cur_area = ptmp; |
} |
return cur_area = NULL; |
} |
|
inline unsigned long evalsim_mem32(unsigned long memaddr) |
{ |
unsigned long temp; |
|
if (verify_memoryarea(memaddr)) { |
switch(cur_area->granularity) { |
case 4: |
temp = cur_area->readfunc(memaddr); |
mem_cycles += cur_area->delayr; |
break; |
case 1: |
temp = cur_area->readfunc(memaddr) << 24; |
temp |= cur_area->readfunc(memaddr + 1) << 16; |
temp |= cur_area->readfunc(memaddr + 2) << 8; |
temp |= cur_area->readfunc(memaddr + 3); |
mem_cycles += cur_area->delayr * 4; |
break; |
case 2: |
temp = cur_area->readfunc(memaddr) << 16; |
temp |= cur_area->readfunc(memaddr + 2); |
mem_cycles += cur_area->delayr * 2; |
break; |
} |
if (cur_area->log) |
fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp); |
} else { |
printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr); |
except_handle(EXCEPT_BUSERR, cur_vadd); |
temp = 0; |
} |
return temp; |
} |
|
unsigned short evalsim_mem16(unsigned long memaddr) |
{ |
unsigned long temp; |
|
if (verify_memoryarea(memaddr)) { |
switch(cur_area->granularity) { |
case 1: |
temp = cur_area->readfunc(memaddr) << 8; |
temp |= cur_area->readfunc(memaddr + 1); |
mem_cycles += cur_area->delayr * 2; |
break; |
case 2: |
temp = cur_area->readfunc(memaddr); |
mem_cycles += cur_area->delayr; |
break; |
case 4: |
temp = evalsim_mem32 (memaddr & ~3ul); |
if (memaddr & 2) |
temp &= 0xffff; |
else |
temp >>= 16; |
break; |
} |
if (cur_area->log) |
fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp); |
} else { |
printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr); |
except_handle(EXCEPT_BUSERR, cur_vadd); |
temp = 0; |
} |
return temp; |
} |
|
unsigned char evalsim_mem8(unsigned long memaddr) |
{ |
unsigned long temp; |
|
if (verify_memoryarea(memaddr)) { |
switch(cur_area->granularity) { |
case 1: |
temp = cur_area->readfunc(memaddr); |
mem_cycles += cur_area->delayr; |
break; |
case 2: |
temp = evalsim_mem16 (memaddr & ~1ul); |
if (memaddr & 1) |
temp &= 0xff; |
else |
temp >>= 8; |
break; |
case 4: |
temp = evalsim_mem32 (memaddr & ~3ul); |
temp >>= 8 * (3 - (memaddr & 3)); |
temp &= 0xff; |
break; |
} |
if (cur_area->log) |
fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp); |
} else { |
printf("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr); |
except_handle(EXCEPT_BUSERR, cur_vadd); |
temp = 0; |
} |
return temp; |
} |
|
/* Returns 32-bit values from mem array. Big endian version. */ |
unsigned long read_mem(unsigned long memaddr,int* breakpoint) |
{ |
260,7 → 371,8
mprofile (memaddr, MPROF_32 | MPROF_READ); |
|
cur_vadd = memaddr; |
memaddr = simulate_dc_mmu_load(memaddr); |
if (config.dmmu.enabled) |
memaddr = simulate_dc_mmu_load(memaddr); |
if (pending.valid) |
return 0; |
|
287,7 → 399,7
mprofile (memaddr, MPROF_32 | MPROF_FETCH); |
// memaddr = simulate_ic_mmu_fetch(memaddr); |
cur_vadd = pc; |
ic_simulate_fetch(memaddr); |
IFF (config.ic.enabled) ic_simulate_fetch(memaddr); |
if (config.debug.enabled) |
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */ |
temp = evalsim_mem32(memaddr); |
296,39 → 408,6
return temp; |
} |
|
unsigned long evalsim_mem32(unsigned long memaddr) |
{ |
unsigned long temp; |
|
if (verify_memoryarea(memaddr)) { |
switch(cur_area->granularity) { |
case 4: |
temp = cur_area->readfunc(memaddr); |
mem_cycles += cur_area->delayr; |
break; |
case 1: |
temp = cur_area->readfunc(memaddr) << 24; |
temp |= cur_area->readfunc(memaddr + 1) << 16; |
temp |= cur_area->readfunc(memaddr + 2) << 8; |
temp |= cur_area->readfunc(memaddr + 3); |
mem_cycles += cur_area->delayr * 4; |
break; |
case 2: |
temp = cur_area->readfunc(memaddr) << 16; |
temp |= cur_area->readfunc(memaddr + 2); |
mem_cycles += cur_area->delayr * 2; |
break; |
} |
if (cur_area->log) |
fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp); |
} else { |
printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr); |
except_handle(EXCEPT_BUSERR, cur_vadd); |
temp = 0; |
} |
return temp; |
} |
|
/* Returns 16-bit values from mem array. Big endian version. */ |
|
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint) |
339,7 → 418,8
mprofile (memaddr, MPROF_16 | MPROF_READ); |
|
cur_vadd = memaddr; |
memaddr = simulate_dc_mmu_load(memaddr); |
if (config.dmmu.enabled) |
memaddr = simulate_dc_mmu_load(memaddr); |
if (pending.valid) |
return 0; |
|
357,40 → 437,6
return temp; |
} |
|
unsigned short evalsim_mem16(unsigned long memaddr) |
{ |
unsigned long temp; |
|
if (verify_memoryarea(memaddr)) { |
switch(cur_area->granularity) { |
case 1: |
temp = cur_area->readfunc(memaddr) << 8; |
temp |= cur_area->readfunc(memaddr + 1); |
mem_cycles += cur_area->delayr * 2; |
break; |
case 2: |
temp = cur_area->readfunc(memaddr); |
mem_cycles += cur_area->delayr; |
break; |
case 4: |
temp = evalsim_mem32 (memaddr & ~3ul); |
if (memaddr & 2) |
temp &= 0xffff; |
else |
temp >>= 16; |
break; |
} |
if (cur_area->log) |
fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp); |
} else { |
printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr); |
except_handle(EXCEPT_BUSERR, cur_vadd); |
temp = 0; |
} |
return temp; |
} |
|
|
/* Returns 8-bit values from mem array. */ |
|
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint) |
401,7 → 447,8
mprofile (memaddr, MPROF_8 | MPROF_READ); |
|
cur_vadd = memaddr; |
memaddr = simulate_dc_mmu_load(memaddr); |
if (config.dmmu.enabled) |
memaddr = simulate_dc_mmu_load(memaddr); |
if (pending.valid) |
return 0; |
if (config.debug.enabled) |
413,52 → 460,19
return temp; |
} |
|
unsigned char evalsim_mem8(unsigned long memaddr) |
{ |
unsigned long temp; |
|
if (verify_memoryarea(memaddr)) { |
switch(cur_area->granularity) { |
case 1: |
temp = cur_area->readfunc(memaddr); |
mem_cycles += cur_area->delayr; |
break; |
case 2: |
temp = evalsim_mem16 (memaddr & ~1ul); |
if (memaddr & 1) |
temp &= 0xff; |
else |
temp >>= 8; |
break; |
case 4: |
temp = evalsim_mem32 (memaddr & ~3ul); |
temp >>= 8 * (3 - (memaddr & 3)); |
temp &= 0xff; |
break; |
} |
if (cur_area->log) |
fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp); |
} else { |
printf("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr); |
except_handle(EXCEPT_BUSERR, cur_vadd); |
temp = 0; |
} |
return temp; |
} |
|
/* Set mem, 32-bit. Big endian version. */ |
|
void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint) |
{ |
|
if (config.sim.mprofile) |
mprofile (memaddr, MPROF_32 | MPROF_WRITE); |
|
cur_vadd = memaddr; |
memaddr = simulate_dc_mmu_store(memaddr); |
if (config.dmmu.enabled) |
memaddr = simulate_dc_mmu_store(memaddr); |
|
/* If we produced exception don't set anything */ |
if (pending.valid == 1) |
if (pending.valid) |
return; |
|
if (memaddr & 3) { |
511,12 → 525,13
{ |
if (config.sim.mprofile) |
mprofile (memaddr, MPROF_16 | MPROF_WRITE); |
|
|
cur_vadd = memaddr; |
memaddr = simulate_dc_mmu_store(memaddr); |
if (config.dmmu.enabled) |
memaddr = simulate_dc_mmu_store(memaddr); |
|
/* If we produced exception don't set anything */ |
if (pending.valid == 1) |
if (pending.valid) |
return; |
|
if (memaddr & 1) { |
567,13 → 582,13
{ |
if (config.sim.mprofile) |
mprofile (memaddr, MPROF_8 | MPROF_WRITE); |
|
|
cur_vadd = memaddr; |
memaddr = simulate_dc_mmu_store(memaddr); |
if (config.dmmu.enabled) |
memaddr = simulate_dc_mmu_store(memaddr); |
|
/* If we produced exception don't set anything */ |
if (pending.valid == 1) |
return; |
if (pending.valid) return; |
|
if (config.debug.enabled) { |
*breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */ |
/trunk/or1ksim/cpu/common/execute.h
17,16 → 17,15
along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
/* This needs a lot of work. */ |
|
#define CURINSN(INSN) (strcmp(cur->insn, (INSN)) == 0) |
|
/*extern machword eval_operand(char *srcoperand,int* breakpoint); |
extern void set_operand(char *dstoperand, unsigned long value,int* breakpoint);*/ |
extern void dumpreg(); |
extern inline void dump_exe_log(); |
extern inline int cpu_clock (); |
extern void cpu_reset (); |
extern void set_reg32(int regno, unsigned long value); |
void dumpreg(); |
inline void dump_exe_log(); |
inline int cpu_clock (); |
void cpu_reset (); |
unsigned long evalsim_reg32(int regno); |
void setsim_reg32(int regno, unsigned long value); |
|
extern unsigned long pcnext; |
/trunk/or1ksim/toplevel.c
51,7 → 51,7
#include "coff.h" |
|
/* CVS revision number. */ |
const char rcsrev[] = "$Revision: 1.68 $"; |
const char rcsrev[] = "$Revision: 1.69 $"; |
|
/* Continuos run versus single step tracing switch. */ |
int cont_run; |
544,7 → 544,7
|
strtoken(linestr, item2, 2); |
strtoken(linestr, item3, 3); |
set_reg32(strtoul(item2, NULL,0), strtoul(item3, NULL, 0)); |
setsim_reg32(strtoul(item2, NULL,0), strtoul(item3, NULL, 0)); |
} else |
if (strcmp(item1, "pc") == 0) { /* patch PC */ |
char item2[20]; |