URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 122 to Rev 123
- ↔ Reverse comparison
Rev 122 → Rev 123
/trunk/or1ksim/configure
1916,7 → 1916,11
|
|
|
cat >> confdefs.h <<\EOF |
#define HAS_EXECUTION 1 |
EOF |
|
|
INCLUDES="-I\${top_srcdir}/cpu/common -I\${top_srcdir}/cpu/or1k \ |
-I\${top_srcdir}/cpu/$CPU_ARCH -I\${top_srcdir}/cache -I\${top_srcdir}/mmu \ |
-I\${top_srcdir}/bpb -I\${top_srcdir}/peripheral -I\${top_srcdir}/tick \ |
/trunk/or1ksim/sim-config.h
24,6 → 24,12
#define VIRTUAL 1 |
#define PHYSICAL 2 |
|
typedef struct MemoryBlock { |
int address; |
char* file; |
struct MemoryBlock* next; |
} MemoryBlock; |
|
struct config { |
struct { |
int tagtype; |
52,6 → 58,12
int history; /* Instruction stream history remembered by the simulator */ |
int superscalar;/* "Superscalar" simulation */ |
int slp; |
int inhibit_server; /* Don't start up the JTAG proxy server */ |
int server_port; /* A user specified port number for services */ |
int pattern_mem; /* A user specified memory initialization pattern */ |
int random_mem; /* Initialize the memory with random values */ |
MemoryBlock* memory; /* New style memory initializer file (CZ) */ |
char* filename; /* Original Command Simulator file (CZ) */ |
}; |
|
extern struct config config; |
/trunk/or1ksim/Makefile.in
97,7 → 97,7
sim_SOURCES = toplevel.c sim-config.c |
sim_LDADD = cpu/common/libcommon.a cpu/$(CPU_ARCH)/libarch.a cpu/or1k/libor1k.a support/libsupport.a mmu/libmmu.a bpb/libbpb.a cache/libcache.a peripheral/libperipheral.a tick/libtick.a pm/libpm.a pic/libpic.a |
|
sim_LDFLAGS = -lreadline |
sim_LDFLAGS = #-lreadline |
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 |
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs |
CONFIG_HEADER = config.h |
117,9 → 117,10
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
CCLD = $(CC) |
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ |
DIST_COMMON = README ./stamp-h.in COPYING Makefile.am Makefile.in \ |
aclocal.m4 config.guess config.h.in config.sub configure configure.in \ |
install-sh missing mkinstalldirs |
DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \ |
Makefile.am Makefile.in NEWS TODO acconfig.h aclocal.m4 config.guess \ |
config.h.in config.sub configure configure.in install-sh missing \ |
mkinstalldirs |
|
|
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) |
163,7 → 164,7
rm -f $(srcdir)/stamp-h.in; \ |
$(MAKE) $(srcdir)/stamp-h.in; \ |
else :; fi |
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) |
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h |
cd $(top_srcdir) && $(AUTOHEADER) |
@echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null |
|
/trunk/or1ksim/configure.in
95,6 → 95,7
AC_SUBST(SUMVERSION) |
AC_SUBST(TERMCAP_LIB) |
|
AC_DEFINE(HAS_EXECUTION) |
|
dnl yuck |
INCLUDES="-I\${top_srcdir}/cpu/common -I\${top_srcdir}/cpu/or1k \ |
/trunk/or1ksim/cpu/or32/execute.c
24,8 → 24,9
#include <string.h> |
#include <ctype.h> |
|
#include "config.h" |
#include "arch.h" |
|
#include "or32.h" |
#include "branch_predict.h" |
#include "abstract.h" |
#include "parse.h" |
35,6 → 36,7
#include "except.h" |
#include "sprs.h" |
#include "sim-config.h" |
#include "debug_unit.h" |
|
/* General purpose registers. */ |
machword reg[MAX_GPRS]; |
67,6 → 69,9
/* Temporary program counter */ |
unsigned long pcnext; |
|
/* Delay instruction effective address register */ |
unsigned long pcdelay; |
|
/* CCR */ |
int flag; |
|
215,7 → 220,7
XX - relative or absolute address (labels) |
n(XX) - register indirect (with displacement) */ |
|
machword eval_operand(char *srcoperand) |
machword eval_operand(char *srcoperand,int* breakpoint) |
{ |
char operand[OPERANDNAME_LEN]; |
|
233,7 → 238,7
if ((operand[3] == '-') || isdigit(operand[3])) |
return (unsigned long)strtol(&operand[3], NULL, 0) & 0xffff; |
else |
return eval_operand(&operand[3]) & 0xffff; |
return eval_operand(&operand[3],breakpoint) & 0xffff; |
} else |
if (strncmp(operand, "hi(", 3) == 0) { |
*strchr(operand, ')') = '\0'; |
240,7 → 245,7
if ((operand[3] == '-') || isdigit(operand[3])) |
return (unsigned long)strtol(&operand[3], NULL, 0) >> 16; |
else |
return eval_operand(&operand[3]) >> 16; |
return eval_operand(&operand[3],breakpoint) >> 16; |
} else |
if (!strstr(operand, "(")) /* not indirect but ...*/ |
if (*operand == 'r') /* ... register direct */ |
260,7 → 265,7
debug("eval_operand: regstr=%s", regstr); |
memaddr = eval_reg(regstr) + disp; |
|
return eval_mem32(memaddr); |
return eval_mem32(memaddr,breakpoint); |
} |
|
return 0; |
270,7 → 275,7
Set destination operand (register direct, register indirect |
(with displacement) with value. */ |
|
void set_operand(char *dstoperand, unsigned long value) |
void set_operand(char *dstoperand, unsigned long value,int* breakpoint) |
{ |
char operand[OPERANDNAME_LEN]; |
|
288,7 → 293,7
else { /* ... rel. or abs. address */ |
/* printf("INTERNAL ERROR: Can't set addr operand.\n"); |
cont_run = 0; */ |
set_mem32(eval_label(operand), value); |
set_mem32(eval_label(operand), value,breakpoint); |
} |
else { /* register indirect */ |
int disp; /* with possible displacement */ |
300,7 → 305,7
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */ |
memaddr = eval_reg(regstr) + disp; |
|
set_mem32(memaddr, value); |
set_mem32(memaddr, value,breakpoint); |
} |
|
return; |
316,42 → 321,105
memset(iqueue, 0, sizeof(iqueue)); |
memset(icomplet, 0, sizeof(icomplet)); |
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_EXR | SPR_SR_SUPV); |
pcnext = eval_label("_main"); |
if(!GlobalMode) /* Original code */ |
pcnext = eval_label("_reset"); |
else |
pcnext = 0x0000; /* New mode */ |
pc = pcnext; |
pc_phy = pc; |
pcnext += 4; |
ResetDebugUnit(); |
debug("reset ..."); |
set_reg32(STACK_REG, (MEMORY_START + MEMORY_LEN) - STACK_SIZE); |
if(!GlobalMode) /* Original mode */ |
set_reg32(STACK_REG, (MEMORY_START + MEMORY_LEN) - STACK_SIZE); |
except_handle(EXCEPT_RESET, 0); |
} |
|
void fetch() |
{ |
|
/* Modified by CZ 26/05/01 for new mode execution */ |
/* Fetch returns nonzero if instruction should NOT be executed. */ |
int fetch() { |
debug("fetch()\n"); |
|
/* MM: Check for breakpoint. This has to be done in fetch cycle, |
because of peripheria. */ |
if (mem[pc_phy].brk) |
return 1; /* Breakpoint set. */ |
|
/* Cycles after reset. */ |
cycles++; |
|
/* Added by CZ...catch alignment exception here */ |
if(pc_phy & 0x03) |
{ |
except_handle(EXCEPT_ALIGN,0); |
return 0; /* We will fetch exception wrapper at new location. */ |
} |
|
if(pc_phy > MEMORY_START + MEMORY_LEN) |
pc_phy %= MEMORY_START + MEMORY_LEN; |
|
debug("fetch()\n"); |
/* Fetch instruction. */ |
strcpy(iqueue[0].insn, mem[pc_phy].insn->insn); |
if(GlobalMode && !mem[pc_phy].insn) /* If in new mode, then we may need |
to dissasemble this memory location */ |
{ |
unsigned int insn = *((unsigned int*)&mem[pc_phy]); |
int len = disassemble_insn(insn); |
char sTemp[256]; |
extern char *disassembled; |
char *code = NULL; |
char *args = NULL; |
char *s; |
int breakpoint = 0; |
|
sprintf(sTemp, "%u", insn); |
adddataword(sTemp,&breakpoint); |
strcpy(sTemp,disassembled); |
|
/* Trim the whitespace from the end of the string */ |
for(len = strlen(sTemp);len > 0 && isspace(sTemp[len-1]); len--); |
sTemp[len] = '\0'; |
|
/* Trim the whitespace from the beginning of the string */ |
for(s = sTemp;*s && isspace(*s);s++); |
code = s; |
|
/* Skip over the opcode */ |
for(;*s && !isspace(*s);s++); |
if(*s) |
{ |
*s++ = '\0'; |
for(;*s && isspace(*s);s++); |
args = s; |
} |
|
addprogram(code,args,pc_phy,&breakpoint); |
} |
|
strcpy(iqueue[0].op1, mem[pc_phy].insn->op1); |
strcpy(iqueue[0].op2, mem[pc_phy].insn->op2); |
strcpy(iqueue[0].op3, mem[pc_phy].insn->op3); |
strcpy(iqueue[0].op4, mem[pc_phy].insn->op4); |
iqueue[0].insn_index = mem[pc_phy].insn->insn_index; |
iqueue[0].insn_addr = pc; |
iqueue[0].dependdst = NULL; |
iqueue[0].dependsrc1 = NULL; |
iqueue[0].dependsrc2 = NULL; |
|
/*************************************************/ |
/* THIS HAS BEEN DELAYED UNTIL AFTER EXECUTION */ |
/*************************************************/ |
/* Increment program counter. */ |
pc = pcnext; |
#if 0 |
pc = pcnext; |
pcnext += 4; |
|
/* Simulate instruction cache and IMMU. */ |
pc_phy = simulate_ic_mmu_fetch(pc); |
|
if ((pc_phy < MEMORY_START) || (pc_phy > MEMORY_START + MEMORY_LEN) || !mem[pc_phy].insn) { |
if ((pc_phy < MEMORY_START) || (pc_phy > MEMORY_START + MEMORY_LEN) || |
(!mem[pc_phy].insn && !GlobalMode)) { |
except_handle(EXCEPT_BUSERR, pc); |
return; |
return 0; |
} |
|
/* Check for breakpoint. */ |
359,546 → 427,81
cont_run = 0; /* Breakpoint set. */ |
|
nop_period++; |
return; |
#endif |
return 0; |
} |
|
void decode_execute(struct iqueue_entry *cur) |
/* Added by CZ on 27/05/01 */ |
void update_pc() |
{ |
int next_delay_insn = 0; |
|
cur->dependdst = cur->op1; |
cur->dependsrc1 = cur->op2; /* for calculating register */ |
cur->dependsrc2 = cur->op3; /* dependency */ |
|
cur->func_unit = unknown; |
|
if (CURINSN("l.sfne") || CURINSN("l.sfnei")) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = eval_operand(cur->op1) != eval_operand(cur->op2); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} else |
if (CURINSN("l.bf")) { |
cur->func_unit = branch; |
cur->dependsrc1 = ccr_flag; |
if (eval_operand(cur->op1) >= pc) |
mstats.bnez.forward++; |
else |
mstats.bnez.backward++; |
mstats.sbp_bf.all++; |
if (flag) { |
char *endptr; |
pc = pcnext; |
pcnext = delay_insn ? pcdelay : pcnext+4; |
|
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nl.bf relative: pc=%x pcnext=%x\n", pc, pcnext); |
pcnext = pc + (signed)eval_operand(cur->op1) * 4 - 4; |
} else |
pcnext = eval_operand(cur->op1); |
|
if (eval_operand(cur->op1) < pc) |
mstats.sbp_bf.correct++; |
mstats.bnez.taken++; |
bpb_update(cur->insn_addr, 1); |
btic_update(pcnext); |
next_delay_insn = 1; |
} else { |
mstats.bnez.nottaken++; |
bpb_update(cur->insn_addr, 0); |
btic_update(pc); |
} |
} else |
if (CURINSN("l.add")) { |
signed long temp3, temp2, temp1; |
signed char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp1 = temp2 + temp3; |
set_operand(cur->op1, temp1); |
|
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
} else |
if (CURINSN("l.sw")) { |
cur->func_unit = store; |
set_operand(cur->op1, eval_operand(cur->op2)); |
} else |
if (CURINSN("l.sb")) { |
cur->func_unit = store; |
set_operand(cur->op1, (eval_operand(cur->op2) << 24) + (eval_operand(cur->op1) & 0xffffff)); |
} else |
if (CURINSN("l.sh")) { |
cur->func_unit = store; |
set_operand(cur->op1, (eval_operand(cur->op2) << 16) + (eval_operand(cur->op1) & 0xffff)); |
} else |
if (CURINSN("l.lw") || CURINSN("l.lwz")) { |
cur->func_unit = load; |
set_operand(cur->op1, eval_operand(cur->op2)); |
} else |
if (CURINSN("l.lbs")) { |
signed char temp = (eval_operand(cur->op2) >> 24); |
cur->func_unit = load; |
set_operand(cur->op1, temp); |
} else |
if (CURINSN("l.lbz")) { |
unsigned char temp = (eval_operand(cur->op2) >> 24); |
cur->func_unit = load; |
set_operand(cur->op1, temp); |
} else |
if (CURINSN("l.lhs")) { |
signed short temp = (eval_operand(cur->op2) >> 16); |
cur->func_unit = load; |
set_operand(cur->op1, temp); |
} else |
if (CURINSN("l.lhz")) { |
unsigned short temp = (eval_operand(cur->op2) >> 16); |
cur->func_unit = load; |
set_operand(cur->op1, temp); |
} else |
if (CURINSN("l.movhi")) { |
cur->func_unit = movimm; |
set_operand(cur->op1, eval_operand(cur->op2) << 16); |
} else |
if (CURINSN("l.and") || CURINSN("l.andi")) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) & (unsigned)eval_operand(cur->op3)); |
} else |
if (CURINSN("l.or") || CURINSN("l.ori")) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) | (unsigned)eval_operand(cur->op3)); |
} else |
if (CURINSN("l.xor")) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) ^ (signed)eval_operand(cur->op3)); |
} else |
if (CURINSN("l.xori")) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) ^ (signed)eval_operand(cur->op3)); |
} else |
if (CURINSN("l.addi")) { |
signed long temp3, temp2, temp1; |
signed char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp1 = temp2 + temp3; |
debug("l.addi: %x = %x + %x\n", temp1, temp2, temp3); |
set_operand(cur->op1, temp1); |
|
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
} else |
if (CURINSN("l.sub")) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp1 = temp2 - temp3; |
set_operand(cur->op1, temp1); |
} else |
if (CURINSN("l.subi")) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp1 = temp2 - temp3; |
set_operand(cur->op1, temp1); |
} else |
if (CURINSN("l.mul")) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp1 = temp2 * temp3; |
set_operand(cur->op1, temp1); |
} else |
if (CURINSN("l.div")) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
if (temp3) |
temp1 = temp2 / temp3; |
else |
except_handle(EXCEPT_ILLEGAL, 0); |
set_operand(cur->op1, temp1); |
} else |
if (CURINSN("l.divu")) { |
unsigned long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp1 = temp2 / temp3; |
/* cycles += 16; */ |
set_operand(cur->op1, temp1); |
} else |
if (CURINSN("l.sll") || CURINSN("l.slli")) { |
int sign = 1; |
cur->func_unit = shift; |
if ((signed)eval_operand(cur->op2) < 0) |
sign = -1; |
/* cycles += 2; */ |
set_operand(cur->op1, eval_operand(cur->op2) << eval_operand(cur->op3)); |
} else |
if (CURINSN("l.sra") || CURINSN("l.srai")) { |
unsigned long sign = 0; |
cur->func_unit = shift; |
|
if ((signed)eval_operand(cur->op2) < 0) |
sign = -1; |
/* cycles += 2; */ |
set_operand(cur->op1, (signed)eval_operand(cur->op2) / (1 << eval_operand(cur->op3))); |
} else |
if (CURINSN("l.srl") || CURINSN("l.srli")) { |
cur->func_unit = shift; |
/* cycles += 2; */ |
set_operand(cur->op1, eval_operand(cur->op2) >> eval_operand(cur->op3)); |
} else |
if (CURINSN("l.j")) { |
char *endptr; |
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nl.j relative: pc=%x pcnext=%x\n", pc, pcnext); |
pcnext = pc + (signed)eval_operand(cur->op1) * 4 - 4; |
} else |
pcnext = eval_operand(cur->op1); |
cur->func_unit = jump; |
next_delay_insn = 1; |
} else |
if (CURINSN("l.jal")) { |
char *endptr; |
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nl.jal relative: pc=%x pcnext=%x\n", pc, pcnext); |
pcnext = pc + (signed)eval_operand(cur->op1) * 4 - 4; |
} else |
pcnext = eval_operand(cur->op1); |
|
cur->func_unit = jump; |
set_reg32(LINK_REG, pc + 4); |
slp_func_entry(); |
next_delay_insn = 1; |
} else |
if (CURINSN("l.jalr")) { |
cur->func_unit = jump; |
pcnext = eval_operand(cur->op1); |
set_reg32(LINK_REG, pc + 4); |
slp_func_exit(); |
next_delay_insn = 1; |
} else |
if (CURINSN("l.jr")) { |
cur->func_unit = jump; |
pcnext = eval_operand(cur->op1); |
next_delay_insn = 1; |
} else |
if (CURINSN("l.rfe")) { |
cur->func_unit = exception; |
pcnext = mfspr(SPR_EPCR_BASE); |
mtspr(SPR_SR, mfspr(SPR_ESR_BASE)); |
next_delay_insn = 1; |
} else |
if (CURINSN("l.nop")) { |
cur->func_unit = nop; |
if (nop_period > nop_maxperiod) |
nop_maxperiod = nop_period; |
nop_period = 0; |
nops++; |
} else |
if (CURINSN("l.bnf")) { |
cur->func_unit = branch; |
cur->dependsrc1 = ccr_flag; |
if (eval_operand(cur->op1) >= pc) |
mstats.beqz.forward++; |
else |
mstats.beqz.backward++; |
mstats.sbp_bnf.all++; |
if (flag == 0) { |
char *endptr; |
|
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nl.bnf relative: pc=%x pcnext=%x\n", pc, pcnext); |
pcnext = pc + (signed)eval_operand(cur->op1) * 4 - 4; |
} else |
pcnext = eval_operand(cur->op1); |
|
mstats.beqz.taken++; |
bpb_update(cur->insn_addr, 1); |
btic_update(pcnext); |
next_delay_insn = 1; |
} else { |
if (eval_operand(cur->op1) >= pc) |
mstats.sbp_bnf.correct++; |
mstats.beqz.nottaken++; |
bpb_update(cur->insn_addr, 0); |
btic_update(pc); |
} |
} else |
if (CURINSN("l.sfeq") || CURINSN("l.sfeqi")) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = eval_operand(cur->op1) == eval_operand(cur->op2); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} else |
if (CURINSN("l.sfgts") || CURINSN("l.sfgtsi")) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1) > |
(signed)eval_operand(cur->op2); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} else |
if (CURINSN("l.sfges") || CURINSN("l.sfgesi")) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1) >= |
(signed)eval_operand(cur->op2); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} else |
if (CURINSN("l.sflts") || CURINSN("l.sfltsi")) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1) < |
(signed)eval_operand(cur->op2); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} else |
if (CURINSN("l.sfles") || CURINSN("l.sflesi")) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1) <= |
(signed)eval_operand(cur->op2); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} else |
if (CURINSN("l.sfgtu") || CURINSN("l.sfgtui")) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1) > |
(unsigned)eval_operand(cur->op2); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} else |
if (CURINSN("l.sfgeu") || CURINSN("l.sfgeui")) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1) >= |
(unsigned) eval_operand(cur->op2); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} else |
if (CURINSN("l.sfltu") || CURINSN("l.sfltui")) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1) < |
(unsigned)eval_operand(cur->op2); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} else |
if (CURINSN("l.sfleu") || CURINSN("l.sfleui")) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1) <= |
(unsigned)eval_operand(cur->op2); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} else |
if (CURINSN("l.mtspr")) { |
cur->func_unit = move; |
if (mfspr(SPR_SR) & SPR_SR_SUPV) |
mtspr(eval_operand(cur->op1) + eval_operand(cur->op3), eval_operand(cur->op2)); |
else { |
printf("WARNING: trying to write SPR while SR[SUPV] is cleared.\n"); |
cont_run = 0; |
} |
} else |
if (CURINSN("l.mfspr")) { |
cur->func_unit = move; |
if (mfspr(SPR_SR) & SPR_SR_SUPV) |
set_operand(cur->op1, mfspr(eval_operand(cur->op2) + eval_operand(cur->op3))); |
else { |
set_operand(cur->op1, 0); |
printf("WARNING: trying to read SPR while SR[SUPV] is cleared.\n"); |
cont_run = 0; |
} |
} else |
if (CURINSN("simrdtsc")) { /* obsolete */ |
set_operand(cur->op1, cycles + loadcycles + storecycles); |
} else |
if (CURINSN("simprintf")) { /* obsolete */ |
unsigned long stackaddr, fmtaddr, args; |
|
stackaddr = eval_reg(FRAME_REG); |
simprintf(stackaddr, eval_reg("r3")); |
debug("simprintf %x %x %x\n", stackaddr, fmtaddr, args); |
} else |
if (CURINSN("l.sys")) { |
if (eval_operand(cur->op1) > 200) { |
unsigned long stackaddr, fmtaddr, args; |
switch (eval_operand(cur->op1)) { |
case 201: |
set_operand("r9", cycles + loadcycles + storecycles); |
break; |
case 202: |
simprintf(stackaddr, eval_reg("r3")); |
debug("simprintf %x %x %x\n", stackaddr, fmtaddr, args); |
break; |
case 203: |
printf("syscall exit(%d)\n", eval_operand("r3")); |
cont_run = 0; |
break; |
case 204: { |
unsigned long startaddr; |
unsigned long endaddr; |
|
/* if ((startaddr = eval_mem32(eval_reg("r4"))) == -1) |
startaddr = (freemem & ~(PAGE_SIZE)) + PAGE_SIZE; */ |
startaddr = 0x80000000; |
printf("sys 204: startaddr=%x virtphy=%x\n", startaddr, eval_reg("r5")); |
fflush(stdout); |
endaddr = loadcode(simgetstr(stackaddr, eval_reg("r3")), startaddr, eval_reg("r5")); |
set_reg32("r9", endaddr); |
/* setsim_mem32(eval_reg("r4"), startaddr); |
setsim_mem32(eval_reg("r5"), endaddr);*/ |
break; |
} |
default: |
} |
} |
else |
except_handle(EXCEPT_SYSCALL, 0); |
} else |
except_handle(EXCEPT_ILLEGAL, 0); |
|
if (config.dependstats) { |
/* Simulate instruction cache and IMMU. */ |
pc_phy = simulate_ic_mmu_fetch(pc); |
|
/* Dynamic, dependency stats. */ |
adddstats(icomplet[0].insn, iqueue[0].insn, 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, 1, 0); |
} |
|
if (config.superscalar) { |
if ((cur->func_unit == branch) || (cur->func_unit == jump)) |
storecycles += 0; |
|
if (cur->func_unit == store) |
storecycles += 0; |
|
if (cur->func_unit == load) |
loadcycles += 0; |
|
if ((icomplet[0].func_unit == load) && check_depend()) |
loadcycles++; |
|
/* 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[unknown] = 2; |
multissue[shift] = 2; |
multissue[compare] = 1; |
multissue[branch] = 1; |
multissue[jump] = 1; |
multissue[extend] = 2; |
multissue[nop] = 2; |
multissue[move] = 2; |
multissue[movimm] = 2; |
multissue[arith] = 2; |
multissue[store] = 2; |
multissue[load] = 2; |
} |
multissue[cur->func_unit]--; |
issued_per_cycle--; |
} |
delay_insn = next_delay_insn; |
|
return; |
if ((pc_phy < MEMORY_START) || (pc_phy > MEMORY_START + MEMORY_LEN) || |
(!mem[pc_phy].insn && !GlobalMode)) { |
except_handle(EXCEPT_BUSERR, pc); |
return; |
} |
|
nop_period++; |
} |
|
|
void analysis() |
{ |
int i; |
|
/* Here comes real execution someday... */ |
|
if (config.dependency) { |
|
/* Instruction waits in completition buffer until retired. */ |
strcpy(icomplet[0].insn, iqueue[0].insn); |
strcpy(icomplet[0].op1, iqueue[0].op1); |
strcpy(icomplet[0].op2, iqueue[0].op2); |
strcpy(icomplet[0].op3, iqueue[0].op3); |
strcpy(icomplet[0].op4, iqueue[0].op4); |
icomplet[0].func_unit = iqueue[0].func_unit; |
icomplet[0].insn_addr = iqueue[0].insn_addr; |
|
if (iqueue[0].dependdst == iqueue[0].op1) |
icomplet[0].dependdst = icomplet[0].op1; |
else |
if (iqueue[0].dependdst == iqueue[0].op2) |
icomplet[0].dependdst = icomplet[0].op2; |
else |
if (iqueue[0].dependdst == iqueue[0].op3) |
icomplet[0].dependdst = icomplet[0].op3; |
else |
icomplet[0].dependdst = NULL; |
|
if (iqueue[0].dependsrc1 == iqueue[0].op1) |
icomplet[0].dependsrc1 = icomplet[0].op1; |
else |
if (iqueue[0].dependsrc1 == iqueue[0].op2) |
icomplet[0].dependsrc1 = icomplet[0].op2; |
else |
if (iqueue[0].dependsrc1 == iqueue[0].op3) |
icomplet[0].dependsrc1 = icomplet[0].op3; |
else |
icomplet[0].dependsrc1 = NULL; |
|
if (iqueue[0].dependsrc2 == iqueue[0].op1) |
icomplet[0].dependsrc2 = icomplet[0].op1; |
else |
if (iqueue[0].dependsrc2 == iqueue[0].op2) |
icomplet[0].dependsrc2 = icomplet[0].op2; |
else |
if (iqueue[0].dependsrc2 == iqueue[0].op3) |
icomplet[0].dependsrc2 = icomplet[0].op3; |
else |
icomplet[0].dependsrc2 = NULL; |
} |
|
if (config.history) { |
/* History of execution */ |
for (i = HISTEXEC_LEN - 1; i; i--) |
histexec[i] = histexec[i - 1]; |
histexec[0] = icomplet[0].insn_addr; /* add last insn */ |
} |
|
return; |
int i; |
|
/* Here comes real execution someday... */ |
|
if (config.dependency) { |
/* Instruction waits in completition buffer until retired. */ |
strcpy(icomplet[0].op1, iqueue[0].op1); |
strcpy(icomplet[0].op2, iqueue[0].op2); |
strcpy(icomplet[0].op3, iqueue[0].op3); |
strcpy(icomplet[0].op4, iqueue[0].op4); |
icomplet[0].func_unit = iqueue[0].func_unit; |
icomplet[0].insn_addr = iqueue[0].insn_addr; |
icomplet[0].insn_index = iqueue[0].insn_index; |
|
if (iqueue[0].dependdst == iqueue[0].op1) |
icomplet[0].dependdst = icomplet[0].op1; |
else if (iqueue[0].dependdst == iqueue[0].op2) |
icomplet[0].dependdst = icomplet[0].op2; |
else if (iqueue[0].dependdst == iqueue[0].op3) |
icomplet[0].dependdst = icomplet[0].op3; |
else |
icomplet[0].dependdst = NULL; |
|
if (iqueue[0].dependsrc1 == iqueue[0].op1) |
icomplet[0].dependsrc1 = icomplet[0].op1; |
else if (iqueue[0].dependsrc1 == iqueue[0].op2) |
icomplet[0].dependsrc1 = icomplet[0].op2; |
else if (iqueue[0].dependsrc1 == iqueue[0].op3) |
icomplet[0].dependsrc1 = icomplet[0].op3; |
else |
icomplet[0].dependsrc1 = NULL; |
|
if (iqueue[0].dependsrc2 == iqueue[0].op1) |
icomplet[0].dependsrc2 = icomplet[0].op1; |
else if (iqueue[0].dependsrc2 == iqueue[0].op2) |
icomplet[0].dependsrc2 = icomplet[0].op2; |
else if (iqueue[0].dependsrc2 == iqueue[0].op3) |
icomplet[0].dependsrc2 = icomplet[0].op3; |
else |
icomplet[0].dependsrc2 = NULL; |
} |
|
if (config.history) { |
/* History of execution */ |
for (i = HISTEXEC_LEN - 1; i; i--) |
histexec[i] = histexec[i - 1]; |
histexec[0] = icomplet[0].insn_addr; /* add last insn */ |
} |
|
return; |
} |
|
void dumpreg() |
919,3 → 522,520
} |
printf("flag: %u\n", flag); |
} |
|
static struct iqueue_entry *cur; |
static int next_delay_insn = 0; |
static int breakpoint = 0; |
/* Address calculation changed by CZ on 27/05/01 */ |
void decode_execute(struct iqueue_entry *current) |
{ |
next_delay_insn = 0; |
breakpoint = 0; |
|
/* MM: temporary exception disabling. */ |
if (temp_disable_except > 0) |
temp_disable_except--; |
|
if(CheckDebugUnit(DebugInstructionFetch,pc_phy)) |
breakpoint++; |
|
cur = current; |
cur->dependdst = cur->op1; |
cur->dependsrc1 = cur->op2; /* for calculating register */ |
cur->dependsrc2 = cur->op3; /* dependency */ |
|
cur->func_unit = unknown; |
|
/* 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) |
l_invalid(); |
else |
or32_opcodes[cur->insn_index].exec(); |
|
if (config.dependstats) { |
|
/* Dynamic, dependency stats. */ |
adddstats((char *)insn_name(icomplet[0].insn_index), (char *)insn_name(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((char *)insn_name(iqueue[0].insn_index), 1, 0); |
} |
|
if (config.superscalar) { |
if ((cur->func_unit == branch) || (cur->func_unit == jump)) |
storecycles += 0; |
|
if (cur->func_unit == store) |
storecycles += 0; |
|
if (cur->func_unit == load) |
loadcycles += 0; |
|
if ((icomplet[0].func_unit == load) && check_depend()) |
loadcycles++; |
|
/* 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[unknown] = 2; |
multissue[shift] = 2; |
multissue[compare] = 1; |
multissue[branch] = 1; |
multissue[jump] = 1; |
multissue[extend] = 2; |
multissue[nop] = 2; |
multissue[move] = 2; |
multissue[movimm] = 2; |
multissue[arith] = 2; |
multissue[store] = 2; |
multissue[load] = 2; |
} |
multissue[cur->func_unit]--; |
issued_per_cycle--; |
} |
delay_insn = next_delay_insn; |
|
if(breakpoint) |
except_handle(EXCEPT_BREAK,0); |
|
return; |
} |
|
/****************************************** |
* Instruction specific functions. * |
******************************************/ |
|
void l_sfne() { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = eval_operand(cur->op1,&breakpoint) != eval_operand(cur->op2,&breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
void l_bf() { |
cur->func_unit = branch; |
cur->dependsrc1 = ccr_flag; |
if (eval_operand(cur->op1,&breakpoint) >= pc) |
mstats.bnez.forward++; |
else |
mstats.bnez.backward++; |
mstats.sbp_bf.all++; |
if (flag) { |
char *endptr; |
|
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nl.bf relative: pc=%x pcnext=%x\n", pc, pcnext); |
pcdelay = pc + (signed)eval_operand(cur->op1,&breakpoint) * 4; |
} else |
pcdelay = eval_operand(cur->op1,&breakpoint); |
|
if (eval_operand(cur->op1,&breakpoint) < pc) |
mstats.sbp_bf.correct++; |
mstats.bnez.taken++; |
bpb_update(cur->insn_addr, 1); |
btic_update(pcnext); |
next_delay_insn = 1; |
} else { |
mstats.bnez.nottaken++; |
bpb_update(cur->insn_addr, 0); |
btic_update(pc); |
} |
} |
void l_add() { |
signed long temp3, temp2, temp1; |
signed char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 + temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
|
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
} |
void l_sw() { |
unsigned long value = eval_operand(cur->op2,&breakpoint); |
cur->func_unit = store; |
set_operand(cur->op1, value,&breakpoint); |
} |
void l_sb() { |
cur->func_unit = store; |
set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 24) + (eval_operand(cur->op1,&breakpoint) & 0xffffff),&breakpoint); |
} |
void l_sh() { |
cur->func_unit = store; |
set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 16) + (eval_operand(cur->op1,&breakpoint) & 0xffff),&breakpoint); |
} |
void l_lwz() { |
cur->func_unit = load; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint); |
} |
void l_lbs() { |
signed char temp = (eval_operand(cur->op2,&breakpoint) >> 24); |
cur->func_unit = load; |
set_operand(cur->op1, temp,&breakpoint); |
} |
void l_lbz() { |
unsigned char temp = (eval_operand(cur->op2,&breakpoint) >> 24); |
cur->func_unit = load; |
set_operand(cur->op1, temp,&breakpoint); |
} |
void l_lhs() { |
signed short temp = (eval_operand(cur->op2,&breakpoint) >> 16); |
cur->func_unit = load; |
set_operand(cur->op1, temp,&breakpoint); |
} |
void l_lhz() { |
unsigned short temp = (eval_operand(cur->op2,&breakpoint) >> 16); |
cur->func_unit = load; |
set_operand(cur->op1, temp,&breakpoint); |
} |
void l_movhi() { |
cur->func_unit = movimm; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << 16,&breakpoint); |
} |
void l_and() { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) & (unsigned)eval_operand(cur->op3,&breakpoint),&breakpoint); |
} |
void l_or() { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) | (unsigned)eval_operand(cur->op3,&breakpoint),&breakpoint); |
} |
void l_xor() { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) ^ (signed)eval_operand(cur->op3,&breakpoint),&breakpoint); |
} |
void l_sub() { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 - temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
} |
void l_mul() { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 * temp3; |
set_operand(cur->op1, temp1,&breakpoint); |
} |
void l_div() { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
if (temp3) |
temp1 = temp2 / temp3; |
else |
except_handle(EXCEPT_ILLEGAL, 0); |
set_operand(cur->op1, temp1,&breakpoint); |
} |
void l_divu() { |
unsigned long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 / temp3; |
/* cycles += 16; */ |
set_operand(cur->op1, temp1,&breakpoint); |
} |
void l_sll() { |
int sign = 1; |
cur->func_unit = shift; |
if ((signed)eval_operand(cur->op2,&breakpoint) < 0) |
sign = -1; |
/* cycles += 2; */ |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << eval_operand(cur->op3,&breakpoint),&breakpoint); |
} |
void l_sra() { |
unsigned long sign = 0; |
cur->func_unit = shift; |
|
if ((signed)eval_operand(cur->op2,&breakpoint) < 0) |
sign = -1; |
/* cycles += 2; */ |
set_operand(cur->op1, (signed)eval_operand(cur->op2,&breakpoint) / (1 << eval_operand(cur->op3,&breakpoint)),&breakpoint); |
} |
void l_srl() { |
cur->func_unit = shift; |
/* cycles += 2; */ |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) >> eval_operand(cur->op3,&breakpoint),&breakpoint); |
} |
void l_j() { |
char *endptr; |
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nl.j relative: pc=%x pcnext=%x\n", pc, pcnext); |
pcdelay = pc + (signed)eval_operand(cur->op1,&breakpoint) * 4; |
} else |
pcdelay = eval_operand(cur->op1,&breakpoint); |
cur->func_unit = jump; |
next_delay_insn = 1; |
} |
void l_jal() { |
char *endptr; |
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nl.jal relative: pc=%x pcnext=%x\n", pc, pcnext); |
pcdelay = pc + (signed)eval_operand(cur->op1,&breakpoint) * 4; |
} else |
pcdelay = eval_operand(cur->op1,&breakpoint); |
|
cur->func_unit = jump; |
set_reg32(LINK_REG, pc + 8); |
slp_func_entry(); |
next_delay_insn = 1; |
} |
void l_jalr() { |
cur->func_unit = jump; |
pcdelay = eval_operand(cur->op1,&breakpoint); |
set_reg32(LINK_REG, pc + 8); |
slp_func_exit(); |
next_delay_insn = 1; |
} |
void l_jr() { |
cur->func_unit = jump; |
pcdelay = eval_operand(cur->op1,&breakpoint); |
next_delay_insn = 1; |
} |
void l_rfe() { |
cur->func_unit = exception; |
pcdelay = mfspr(SPR_EPCR_BASE); |
mtspr(SPR_SR, mfspr(SPR_ESR_BASE)); |
next_delay_insn = 1; |
if (temp_disable_except == 0) |
temp_disable_except = 1; |
} |
void l_nop() { |
cur->func_unit = nop; |
if (nop_period > nop_maxperiod) |
nop_maxperiod = nop_period; |
nop_period = 0; |
nops++; |
} |
void l_bnf() { |
cur->func_unit = branch; |
cur->dependsrc1 = ccr_flag; |
if (eval_operand(cur->op1,&breakpoint) >= pc) |
mstats.beqz.forward++; |
else |
mstats.beqz.backward++; |
mstats.sbp_bnf.all++; |
if (flag == 0) { |
char *endptr; |
|
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nl.bnf relative: pc=%x pcnext=%x\n", pc, pcnext); |
pcdelay = pc + (signed)eval_operand(cur->op1,&breakpoint) * 4; |
} else |
pcdelay = eval_operand(cur->op1,&breakpoint); |
|
mstats.beqz.taken++; |
bpb_update(cur->insn_addr, 1); |
btic_update(pcnext); |
next_delay_insn = 1; |
} else { |
if (eval_operand(cur->op1,&breakpoint) >= pc) |
mstats.sbp_bnf.correct++; |
mstats.beqz.nottaken++; |
bpb_update(cur->insn_addr, 0); |
btic_update(pc); |
} |
} |
void l_sfeq() { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = eval_operand(cur->op1,&breakpoint) == eval_operand(cur->op2,&breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
void l_sfgts() { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1,&breakpoint) > |
(signed)eval_operand(cur->op2,&breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
void l_sfges() { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1,&breakpoint) >= |
(signed)eval_operand(cur->op2,&breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
void l_sflts() { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1,&breakpoint) < |
(signed)eval_operand(cur->op2,&breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
void l_sfles() { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1,&breakpoint) <= |
(signed)eval_operand(cur->op2,&breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
void l_sfgtu() { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1,&breakpoint) > |
(unsigned)eval_operand(cur->op2,&breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
void l_sfgeu() { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1,&breakpoint) >= |
(unsigned) eval_operand(cur->op2,&breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
void l_sfltu() { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1,&breakpoint) < |
(unsigned)eval_operand(cur->op2,&breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
void l_sfleu() { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1,&breakpoint) <= |
(unsigned)eval_operand(cur->op2,&breakpoint); |
setsprbits(SPR_SR, SPR_SR_F, flag); |
} |
void l_mtspr() { |
cur->func_unit = move; |
if (mfspr(SPR_SR) & SPR_SR_SUPV) |
mtspr(eval_operand(cur->op1,&breakpoint) + eval_operand(cur->op3,&breakpoint), eval_operand(cur->op2,&breakpoint)); |
else { |
printf("WARNING: trying to write SPR while SR[SUPV] is cleared.\n"); |
cont_run = 0; |
} |
} |
void l_mfspr() { |
cur->func_unit = move; |
if (mfspr(SPR_SR) & SPR_SR_SUPV) |
set_operand(cur->op1, mfspr(eval_operand(cur->op2,&breakpoint) + eval_operand(cur->op3,&breakpoint)),&breakpoint); |
else { |
set_operand(cur->op1, 0,&breakpoint); |
printf("WARNING: trying to read SPR while SR[SUPV] is cleared.\n"); |
cont_run = 0; |
} |
} |
void l_sys() { |
int dummy1 = 0; |
int dummy2 = 0; |
int dummy3 = 0; |
|
if (!GlobalMode && eval_operand(cur->op1,&breakpoint) > 200) { |
unsigned long stackaddr, fmtaddr, args; |
switch (eval_operand(cur->op1,&breakpoint)) { |
case 201: |
set_operand("r9", cycles + loadcycles + storecycles,&breakpoint); |
break; |
case 202: |
simprintf(stackaddr, eval_reg("r3")); |
debug("simprintf %x %x %x\n", stackaddr, fmtaddr, args); |
break; |
case 203: |
printf("syscall exit(%d)\n", eval_operand("r3",&breakpoint)); |
cont_run = 0; |
break; |
case 204: { |
unsigned long startaddr; |
unsigned long endaddr; |
|
/* if ((startaddr = eval_mem32(eval_reg("r4"))) == -1) |
startaddr = (freemem & ~(PAGE_SIZE)) + PAGE_SIZE; */ |
startaddr = 0x80000000; |
printf("sys 204: startaddr=%x virtphy=%x\n", startaddr, eval_reg("r5")); |
fflush(stdout); |
endaddr = loadcode(simgetstr(stackaddr, eval_reg("r3")), startaddr, eval_reg("r5")); |
set_reg32("r9", endaddr); |
/* setsim_mem32(eval_reg("r4"), startaddr); |
setsim_mem32(eval_reg("r5"), endaddr);*/ |
break; |
} |
default: |
} |
} |
else |
except_handle(EXCEPT_SYSCALL, 0); |
} |
void l_mac() { |
sprword lo, hi; |
LONGEST l; |
cur->func_unit = mac; |
lo = mfspr (SPR_MACLO); |
hi = mfspr (SPR_MACHI); |
l = (ULONGEST)lo | ((LONGEST)hi) << 32ULL; |
l = (LONGEST) eval_operand(cur->op1,&breakpoint) * (LONGEST)eval_operand(cur->op2,&breakpoint); |
|
/* This implementation is very fast - it needs only one cycle for mac. */ |
lo = l & 0xFFFFFFFF; |
hi = l >> 32ULL; |
mtspr (SPR_MACLO, lo); |
mtspr (SPR_MACHI, hi); |
} |
void l_msb() { |
sprword lo, hi; |
LONGEST l; |
cur->func_unit = mac; |
lo = mfspr (SPR_MACLO); |
hi = mfspr (SPR_MACHI); |
l = (ULONGEST)lo | ((LONGEST)hi) << 32ULL; |
l -= (LONGEST) eval_operand(cur->op1,&breakpoint) * (LONGEST)eval_operand(cur->op2,&breakpoint); |
|
/* This implementation is very fast - it needs only one cycle for msb. */ |
lo = l & 0xFFFFFFFF; |
hi = l >> 32ULL; |
mtspr (SPR_MACLO, lo); |
mtspr (SPR_MACHI, hi); |
} |
void l_macrc() { |
sprword lo, hi; |
LONGEST l; |
/* No need for synchronization here -- all MAC instructions are 1 cycle long. */ |
lo = mfspr (SPR_MACLO); |
set_operand(cur->op1, lo, &breakpoint); |
mtspr (SPR_MACLO, 0); |
} |
void l_invalid() { |
except_handle(EXCEPT_ILLEGAL, 0); |
} |
/trunk/or1ksim/cpu/dlx/execute.c
173,7 → 173,7
XX - relative or absolute address (labels) |
n(XX) - register indirect (with displacement) */ |
|
machword eval_operand(char *srcoperand) |
machword eval_operand(char *srcoperand,int* breakpoint) |
{ |
char operand[OPERANDNAME_LEN]; |
|
198,7 → 198,7
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */ |
memaddr = eval_reg(regstr) + disp; |
|
return eval_mem32(memaddr); |
return eval_mem32(memaddr,breakpoint); |
} |
|
return 0; |
208,7 → 208,7
Set destination operand (register direct, register indirect |
(with displacement) with value. */ |
|
void set_operand(char *dstoperand, unsigned long value) |
void set_operand(char *dstoperand, unsigned long value,int* breakpoint) |
{ |
char operand[OPERANDNAME_LEN]; |
|
232,7 → 232,7
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */ |
memaddr = eval_reg(regstr) + disp; |
|
set_mem32(memaddr, value); |
set_mem32(memaddr, value, breakpoint); |
} |
|
return; |
284,6 → 284,7
|
void decode(struct iqueue_entry *cur) |
{ |
int breakpoint = 0; |
|
cur->dependdst = cur->op1; |
cur->dependsrc1 = cur->op2; /* for calculating register */ |
293,67 → 294,67
|
if (strcmp(cur->insn, "sw") == 0) { |
cur->func_unit = store; |
set_operand(cur->op1, eval_operand(cur->op2)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "sb") == 0) { |
cur->func_unit = store; |
set_operand(cur->op1, (eval_operand(cur->op2) << 24) + (eval_operand(cur->op1) & 0xffffff)); |
set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 24) + (eval_operand(cur->op1,&breakpoint) & 0xffffff),&breakpoint); |
} else |
if (strcmp(cur->insn, "sh") == 0) { |
cur->func_unit = store; |
set_operand(cur->op1, (eval_operand(cur->op2) << 16) + (eval_operand(cur->op1) & 0xffff)); |
set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 16) + (eval_operand(cur->op1,&breakpoint) & 0xffff),&breakpoint); |
} else |
if (strcmp(cur->insn, "lw") == 0) { |
cur->func_unit = load; |
set_operand(cur->op1, eval_operand(cur->op2)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "lb") == 0) { |
signed char temp = (eval_operand(cur->op2) >> 24); |
signed char temp = (eval_operand(cur->op2,&breakpoint) >> 24); |
cur->func_unit = load; |
set_operand(cur->op1, temp); |
set_operand(cur->op1, temp,&breakpoint); |
} else |
if (strcmp(cur->insn, "lbu") == 0) { |
unsigned char temp = (eval_operand(cur->op2) >> 24); |
unsigned char temp = (eval_operand(cur->op2,&breakpoint) >> 24); |
cur->func_unit = load; |
set_operand(cur->op1, temp); |
set_operand(cur->op1, temp,&breakpoint); |
} else |
if (strcmp(cur->insn, "lh") == 0) { |
signed short temp = (eval_operand(cur->op2) >> 16); |
signed short temp = (eval_operand(cur->op2,&breakpoint) >> 16); |
cur->func_unit = load; |
set_operand(cur->op1, temp); |
set_operand(cur->op1, temp,&breakpoint); |
} else |
if (strcmp(cur->insn, "lhu") == 0) { |
unsigned short temp = (eval_operand(cur->op2) >> 16); |
unsigned short temp = (eval_operand(cur->op2,&breakpoint) >> 16); |
cur->func_unit = load; |
set_operand(cur->op1, temp); |
set_operand(cur->op1, temp,&breakpoint); |
} else |
if (strcmp(cur->insn, "lwi") == 0) { |
cur->func_unit = movimm; |
set_operand(cur->op1, eval_operand(cur->op2)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "lhi") == 0) { |
cur->func_unit = movimm; |
set_operand(cur->op1, eval_operand(cur->op2) << 16); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << 16,&breakpoint); |
} else |
if (strcmp(cur->insn, "and") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) & eval_operand(cur->op3)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) & eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "andi") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) & eval_operand(cur->op3)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) & eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "or") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) | eval_operand(cur->op3)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) | eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "ori") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) | eval_operand(cur->op3)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) | eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "xor") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) ^ eval_operand(cur->op3)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) ^ eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "add") == 0) { |
signed long temp3, temp2, temp1; |
360,10 → 361,10
signed char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 + temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
|
temp4 = temp1; |
if (temp4 == temp1) |
374,10 → 375,10
signed char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 + temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
|
temp4 = temp1; |
if (temp4 == temp1) |
388,10 → 389,10
unsigned char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 + temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
|
temp4 = temp1; |
if (temp4 == temp1) |
401,89 → 402,89
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 - temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "subui") == 0) { |
unsigned long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 - temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "subi") == 0) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 - temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "mul") == 0) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 * temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "div") == 0) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 / temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "divu") == 0) { |
unsigned long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 / temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "slli") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, eval_operand(cur->op2) << eval_operand(cur->op3)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "sll") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, eval_operand(cur->op2) << eval_operand(cur->op3)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) << eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "srl") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, eval_operand(cur->op2) >> eval_operand(cur->op3)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) >> eval_operand(cur->op3,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "srai") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, (signed)eval_operand(cur->op2) / (1 << eval_operand(cur->op3))); |
set_operand(cur->op1, (signed)eval_operand(cur->op2,&breakpoint) / (1 << eval_operand(cur->op3,&breakpoint)),&breakpoint); |
} else |
if (strcmp(cur->insn, "sra") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, (signed)eval_operand(cur->op2) / (1 << eval_operand(cur->op3))); |
set_operand(cur->op1, (signed)eval_operand(cur->op2,&breakpoint) / (1 << eval_operand(cur->op3,&breakpoint)),&breakpoint); |
} else |
if (strcmp(cur->insn, "jal") == 0) { |
cur->func_unit = jump; |
pctemp = eval_operand(cur->op1); |
pctemp = eval_operand(cur->op1,&breakpoint); |
set_reg32(LINK_REG, pc + 4); |
} else |
if (strcmp(cur->insn, "jr") == 0) { |
cur->func_unit = jump; |
cur->dependsrc1 = cur->op1; |
pctemp = eval_operand(cur->op1); |
pctemp = eval_operand(cur->op1,&breakpoint); |
} else |
if (strcmp(cur->insn, "j") == 0) { |
cur->func_unit = jump; |
pctemp = eval_operand(cur->op1); |
pctemp = eval_operand(cur->op1,&breakpoint); |
} else |
if (strcmp(cur->insn, "nop") == 0) { |
cur->func_unit = nop; |
491,8 → 492,8
if (strcmp(cur->insn, "beqz") == 0) { |
cur->func_unit = branch; |
cur->dependsrc1 = cur->op1; |
if (eval_operand(cur->op1) == 0) { |
pctemp = eval_operand(cur->op2); |
if (eval_operand(cur->op1,&breakpoint) == 0) { |
pctemp = eval_operand(cur->op2,&breakpoint); |
mstats.beqz.taken++; |
bpb_update(cur->insn_addr, 1); |
btic_update(pctemp); |
505,8 → 506,8
if (strcmp(cur->insn, "bnez") == 0) { |
cur->func_unit = branch; |
cur->dependsrc1 = cur->op1; |
if (eval_operand(cur->op1) != 0) { |
pctemp = eval_operand(cur->op2); |
if (eval_operand(cur->op1,&breakpoint) != 0) { |
pctemp = eval_operand(cur->op2,&breakpoint); |
mstats.bnez.taken++; |
bpb_update(cur->insn_addr, 1); |
btic_update(pctemp); |
518,121 → 519,121
} else |
if (strcmp(cur->insn, "seq") == 0) { |
cur->func_unit = compare; |
if (eval_operand(cur->op2) == eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if (eval_operand(cur->op2,&breakpoint) == eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "snei") == 0) { |
cur->func_unit = compare; |
if (eval_operand(cur->op2) != eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if (eval_operand(cur->op2,&breakpoint) != eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sne") == 0) { |
cur->func_unit = compare; |
if (eval_operand(cur->op2) != eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if (eval_operand(cur->op2,&breakpoint) != eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "seqi") == 0) { |
cur->func_unit = compare; |
if (eval_operand(cur->op2) == eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if (eval_operand(cur->op2,&breakpoint) == eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sgt") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2) > |
(signed)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((signed)eval_operand(cur->op2,&breakpoint) > |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sgtui") == 0) { |
cur->func_unit = compare; |
if ((unsigned)eval_operand(cur->op2) > |
(unsigned)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((unsigned)eval_operand(cur->op2,&breakpoint) > |
(unsigned)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sgeui") == 0) { |
cur->func_unit = compare; |
if ((unsigned)eval_operand(cur->op2) >= |
(unsigned)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((unsigned)eval_operand(cur->op2,&breakpoint) >= |
(unsigned)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sgei") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2) >= (signed)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((signed)eval_operand(cur->op2,&breakpoint) >= (signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sgti") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2) > |
(signed)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((signed)eval_operand(cur->op2,&breakpoint) > |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "slt") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2) < |
(signed)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((signed)eval_operand(cur->op2,&breakpoint) < |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "slti") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2) < |
(signed)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((signed)eval_operand(cur->op2,&breakpoint) < |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sle") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2) <= |
(signed)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((signed)eval_operand(cur->op2,&breakpoint) <= |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "slei") == 0) { |
cur->func_unit = compare; |
if ((signed)eval_operand(cur->op2) <= |
(signed)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((signed)eval_operand(cur->op2,&breakpoint) <= |
(signed)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sleui") == 0) { |
cur->func_unit = compare; |
if ((unsigned)eval_operand(cur->op2) <= |
(unsigned)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((unsigned)eval_operand(cur->op2,&breakpoint) <= |
(unsigned)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "sleu") == 0) { |
cur->func_unit = compare; |
if ((unsigned)eval_operand(cur->op2) <= |
(unsigned)eval_operand(cur->op3)) |
set_operand(cur->op1, 1); |
if ((unsigned)eval_operand(cur->op2,&breakpoint) <= |
(unsigned)eval_operand(cur->op3,&breakpoint)) |
set_operand(cur->op1, 1,&breakpoint); |
else |
set_operand(cur->op1, 0); |
set_operand(cur->op1, 0,&breakpoint); |
} else |
if (strcmp(cur->insn, "simrdtsc") == 0) { |
set_operand(cur->op1, cycles+loadcycles+storecycles+forwardingcycles); |
set_operand(cur->op1, cycles+loadcycles+storecycles+forwardingcycles,&breakpoint); |
} else |
if (strcmp(cur->insn, "simprintf") == 0) { |
unsigned long stackaddr; |
/trunk/or1ksim/cpu/or16/execute.c
214,7 → 214,7
XX - relative or absolute address (labels) |
n(XX) - register indirect (with displacement) */ |
|
machword eval_operand(char *srcoperand) |
machword eval_operand(char *srcoperand,int* breakpoint) |
{ |
char operand[OPERANDNAME_LEN]; |
|
232,7 → 232,7
if ((operand[3] == '-') || isdigit(operand[3])) |
return (unsigned long)strtol(&operand[3], NULL, 0) & 0xffff; |
else |
return eval_operand(&operand[3]) & 0xffff; |
return eval_operand(&operand[3],breakpoint) & 0xffff; |
} else |
if (strncmp(operand, "HI(", 3) == 0) { |
*strchr(operand, ')') = '\0'; |
239,7 → 239,7
if ((operand[3] == '-') || isdigit(operand[3])) |
return (unsigned long)strtol(&operand[3], NULL, 0) >> 16; |
else |
return eval_operand(&operand[3]) >> 16; |
return eval_operand(&operand[3],breakpoint) >> 16; |
} else |
if (!strstr(operand, "(")) /* not indirect but ...*/ |
if (*operand == '%') /* ... register direct */ |
261,7 → 261,7
debug("eval_operand: regstr=%s", regstr); |
memaddr = eval_reg(regstr) + disp; |
|
return eval_mem32(memaddr); |
return eval_mem32(memaddr,breakpoint); |
} |
|
return 0; |
271,7 → 271,7
Set destination operand (register direct, register indirect |
(with displacement) with value. */ |
|
void set_operand(char *dstoperand, unsigned long value) |
void set_operand(char *dstoperand, unsigned long value,int* breakpoint) |
{ |
char operand[OPERANDNAME_LEN]; |
|
289,7 → 289,7
else { /* ... rel. or abs. address */ |
/* printf("INTERNAL ERROR: Can't set addr operand.\n"); |
cont_run = 0; */ |
set_mem32(eval_label(operand), value); |
set_mem32(eval_label(operand), value,breakpoint); |
} |
else { /* register indirect */ |
int disp; /* with possible displacement */ |
310,7 → 310,7
*strstr(regstr, ")") = '\0'; /* regstr == "rXX" */ |
memaddr = eval_reg(regstr) + disp; |
|
set_mem32(memaddr, value); |
set_mem32(memaddr, value, breakpoint); |
} |
|
return; |
438,6 → 438,7
|
void decode(struct iqueue_entry *cur) |
{ |
int breakpoint = 0; |
|
cur->dependdst = cur->op1; |
cur->dependsrc1 = cur->op2; /* for calculating register */ |
455,122 → 456,122
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = eval_operand(cur->op1) == eval_operand(cur->op2); |
flag = eval_operand(cur->op1,&breakpoint) == eval_operand(cur->op2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.sfne32") == 0) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = eval_operand(cur->op1) != eval_operand(cur->op2); |
flag = eval_operand(cur->op1,&breakpoint) != eval_operand(cur->op2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.sfgt32s") == 0) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1) > |
(signed)eval_operand(cur->op2); |
flag = (signed)eval_operand(cur->op1,&breakpoint) > |
(signed)eval_operand(cur->op2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.sfge32s") == 0) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1) >= |
(signed)eval_operand(cur->op2); |
flag = (signed)eval_operand(cur->op1,&breakpoint) >= |
(signed)eval_operand(cur->op2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.sflt32s") == 0) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1) < |
(signed)eval_operand(cur->op2); |
flag = (signed)eval_operand(cur->op1,&breakpoint) < |
(signed)eval_operand(cur->op2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.sfle32s") == 0) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (signed)eval_operand(cur->op1) <= |
(signed)eval_operand(cur->op2); |
flag = (signed)eval_operand(cur->op1,&breakpoint) <= |
(signed)eval_operand(cur->op2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.sfgt32u") == 0) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1) > |
(unsigned)eval_operand(cur->op2); |
flag = (unsigned)eval_operand(cur->op1,&breakpoint) > |
(unsigned)eval_operand(cur->op2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.sfge32u") == 0) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1) >= |
(unsigned) eval_operand(cur->op2); |
flag = (unsigned)eval_operand(cur->op1,&breakpoint) >= |
(unsigned) eval_operand(cur->op2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.sflt32u") == 0) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1) < |
(unsigned)eval_operand(cur->op2); |
flag = (unsigned)eval_operand(cur->op1,&breakpoint) < |
(unsigned)eval_operand(cur->op2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.sfle32u") == 0) { |
cur->func_unit = compare; |
cur->dependsrc2 = cur->op1; |
cur->dependdst = ccr_flag; |
flag = (unsigned)eval_operand(cur->op1) <= |
(unsigned)eval_operand(cur->op2); |
flag = (unsigned)eval_operand(cur->op1,&breakpoint) <= |
(unsigned)eval_operand(cur->op2,&breakpoint); |
} else |
|
if (strcmp(cur->insn, "h.ext16s") == 0) { |
cur->func_unit = extend; |
if ((eval_operand(cur->op1) & 0x8000) == 0x8000) |
set_operand(cur->op1, eval_operand(cur->op1) | 0xffff0000); |
if ((eval_operand(cur->op1,&breakpoint) & 0x8000) == 0x8000) |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) | 0xffff0000,&breakpoint); |
else |
set_operand(cur->op1, eval_operand(cur->op1) & 0x0000ffff); |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) & 0x0000ffff,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.ext8s") == 0) { |
cur->func_unit = extend; |
if ((eval_operand(cur->op1) & 0x80) == 0x80) |
set_operand(cur->op1, eval_operand(cur->op1) | 0xffffff00); |
if ((eval_operand(cur->op1,&breakpoint) & 0x80) == 0x80) |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) | 0xffffff00,&breakpoint); |
else |
set_operand(cur->op1, eval_operand(cur->op1) & 0x000000ff); |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) & 0x000000ff,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.ext16z") == 0) { |
cur->func_unit = extend; |
set_operand(cur->op1, eval_operand(cur->op1) & 0x0000ffff); |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) & 0x0000ffff,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.ext8z") == 0) { |
cur->func_unit = extend; |
set_operand(cur->op1, eval_operand(cur->op1) & 0x000000ff); |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) & 0x000000ff,&breakpoint); |
} else |
|
if (strcmp(cur->insn, "h.load32u") == 0) { |
cur->func_unit = load; |
set_operand(cur->op1, eval_operand(cur->op2)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.load16u") == 0) { |
unsigned short temp = (eval_operand(cur->op2) >> 16); |
unsigned short temp = (eval_operand(cur->op2,&breakpoint) >> 16); |
printf("OOO XXX load16u temp=%x", temp); |
cur->func_unit = load; |
set_operand(cur->op1, temp); |
set_operand(cur->op1, temp,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.load8u") == 0) { |
unsigned char temp = (eval_operand(cur->op2) >> 24); |
unsigned char temp = (eval_operand(cur->op2,&breakpoint) >> 24); |
printf("OOO XXX load8u temp=%x", temp); |
cur->func_unit = load; |
set_operand(cur->op1, temp); |
set_operand(cur->op1, temp,&breakpoint); |
} else |
|
if (strcmp(cur->insn, "h.stor32") == 0) { |
cur->func_unit = store; |
set_operand(cur->op1, eval_operand(cur->op2)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.stor16") == 0) { |
cur->func_unit = store; |
set_operand(cur->op1, (eval_operand(cur->op2) << 16) + (eval_operand(cur->op1) & 0xffff)); |
set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 16) + (eval_operand(cur->op1,&breakpoint) & 0xffff),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.stor8") == 0) { |
cur->func_unit = store; |
set_operand(cur->op1, (eval_operand(cur->op2) << 24) + (eval_operand(cur->op1) & 0xffffff)); |
set_operand(cur->op1, (eval_operand(cur->op2,&breakpoint) << 24) + (eval_operand(cur->op1,&breakpoint) & 0xffffff),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.jmp") == 0) { |
char *endptr; |
582,9 → 583,9
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nh.jmp relative: pc=%x pctemp=%x\n", pc, pctemp); |
pctemp = pc + (signed)eval_operand(cur->op1) - 2; |
pctemp = pc + (signed)eval_operand(cur->op1,&breakpoint) - 2; |
} else |
pctemp = eval_operand(cur->op1); |
pctemp = eval_operand(cur->op1,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.jal") == 0) { |
char *endptr; |
595,9 → 596,9
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nh.jal relative: pc=%x pctemp=%x\n", pc, pctemp); |
pctemp = pc + (signed)eval_operand(cur->op1) - 4; |
pctemp = pc + (signed)eval_operand(cur->op1,&breakpoint) - 4; |
} else |
pctemp = eval_operand(cur->op1); |
pctemp = eval_operand(cur->op1,&breakpoint); |
|
set_reg32(LINK_REG, pc + 4); |
} else |
604,7 → 605,7
if (strcmp(cur->insn, "h.jalr") == 0) { |
cur->func_unit = jump; |
jpbr_flag = 2; /* for half-word insn */ |
pctemp = eval_operand(cur->op1); |
pctemp = eval_operand(cur->op1,&breakpoint); |
set_reg32(LINK_REG, pc + 4); |
} else |
if (strcmp(cur->insn, "h.jr") == 0) { |
611,7 → 612,7
cur->func_unit = jump; |
jpbr_flag = 2; /* for half-word insn */ |
cur->dependsrc1 = cur->op1; |
pctemp = eval_operand(cur->op1); |
pctemp = eval_operand(cur->op1,&breakpoint); |
} else |
|
if (strcmp(cur->insn, "h.bf") == 0) { |
619,7 → 620,7
jpbr_flag = 2; /* for half-word insn */ |
cur->dependsrc1 = ccr_flag; |
no_delay_slot = 1; |
if (eval_operand(cur->op1) >= pc) |
if (eval_operand(cur->op1,&breakpoint) >= pc) |
mstats.bnez.forward++; |
else |
mstats.bnez.backward++; |
629,9 → 630,9
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nh.bf relative: pc=%x pctemp=%x\n", pc, pctemp); |
pctemp = pc + (signed)eval_operand(cur->op1) - 2; |
pctemp = pc + (signed)eval_operand(cur->op1,&breakpoint) - 2; |
} else |
pctemp = eval_operand(cur->op1); |
pctemp = eval_operand(cur->op1,&breakpoint); |
mstats.bnez.taken++; |
bpb_update(cur->insn_addr, 1); |
btic_update(pctemp); |
647,7 → 648,7
jpbr_flag = 2; /* for half-word insn */ |
cur->dependsrc1 = ccr_flag; |
no_delay_slot = 1; |
if (eval_operand(cur->op1) >= pc) |
if (eval_operand(cur->op1,&breakpoint) >= pc) |
mstats.beqz.forward++; |
else |
mstats.beqz.backward++; |
657,9 → 658,9
strtol(cur->op1, &endptr, 0); |
if (*endptr == '\0') { |
debug("\nh.bnf relative: pc=%x pctemp=%x\n", pc, pctemp); |
pctemp = pc + (signed)eval_operand(cur->op1) - 2; |
pctemp = pc + (signed)eval_operand(cur->op1,&breakpoint) - 2; |
} else |
pctemp = eval_operand(cur->op1); |
pctemp = eval_operand(cur->op1,&breakpoint); |
mstats.beqz.taken++; |
bpb_update(cur->insn_addr, 1); |
btic_update(pctemp); |
694,8 → 695,8
signed int temp3, temp2, temp1; |
signed long temp0; |
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
MACLO += temp2 * temp3; /* do accumulation */ |
MACHI = 0; |
} else |
703,8 → 704,8
signed int temp3, temp2, temp1; |
signed long temp0; |
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
temp1 = temp2 * temp3; |
MACLO -= temp1; |
MACHI = 0; |
725,17 → 726,17
#endif |
regno = atoi(cur->op1 + 1); /* Special register number */ |
if(regno == 3) |
MACHI = eval_operand(cur->op2); |
MACHI = eval_operand(cur->op2,&breakpoint); |
else if(regno == 4) |
MACLO = eval_operand(cur->op2); |
MACLO = eval_operand(cur->op2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.mfsr") == 0) { |
int regno; |
regno = atoi(cur->op2 + 1); |
if(regno == 3) |
set_operand(cur->op1, MACHI); |
set_operand(cur->op1, MACHI,&breakpoint); |
else if(regno == 4) |
set_operand(cur->op1, MACLO); |
set_operand(cur->op1, MACLO,&breakpoint); |
} else |
|
if (strcmp(cur->insn, "h.mul32s") == 0) { |
743,35 → 744,35
signed long long temp3, temp2; |
signed long long temp1; |
cur->func_unit = arith; |
temp5 = (signed long) eval_operand(cur->op2); |
temp4 = (signed long) eval_operand(cur->op1); |
temp5 = (signed long) eval_operand(cur->op2,&breakpoint); |
temp4 = (signed long) eval_operand(cur->op1,&breakpoint); |
temp3 = (signed long long) temp5; /* sign extension */ |
temp2 = (signed long long) temp4; |
temp1 = temp2 * temp3; |
MACLO = (unsigned long) (temp1 & (unsigned long long) 0x00000000ffffffff); |
MACHI = temp1 >> 32; |
set_operand(cur->op1, temp2); |
set_operand(cur->op1, temp2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.mul32u") == 0) { |
unsigned long long temp3, temp2; |
unsigned long long temp1; |
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
temp1 = temp2 * temp3; |
MACLO = temp1 & (unsigned long long) 0x00000000ffffffff; |
MACHI = temp1 >> 32; |
set_operand(cur->op1, temp2); |
set_operand(cur->op1, temp2,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.div32s") == 0) { |
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
if(temp3 != 0) { |
temp1 = temp2 / temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} |
else { |
printf("\nDIVISOR ZERO exception\n"); |
782,11 → 783,11
unsigned long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
if(temp3 != 0) { |
temp1 = temp2 / temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} |
else { |
printf("\nDIVISOR ZERO exception\n"); |
797,11 → 798,11
signed long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
if(temp3 != 0) { |
temp1 = temp2 % temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} |
else { |
printf("\nDIVISOR ZERO exception\n"); |
812,11 → 813,11
unsigned long temp3, temp2, temp1; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
if(temp3 != 0) { |
temp1 = temp2 % temp3; |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} |
else { |
printf("\nDIVISOR ZERO exception\n"); |
826,19 → 827,19
|
if (strcmp(cur->insn, "h.movi8se") == 0) { |
cur->func_unit = movimm; |
set_operand(cur->op1, (signed)eval_operand(cur->op2)); |
set_operand(cur->op1, (signed)eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.movi16ze") == 0) { |
cur->func_unit = movimm; |
set_operand(cur->op1, (0x0000ffff & eval_operand(cur->op2)) ); |
set_operand(cur->op1, (0x0000ffff & eval_operand(cur->op2,&breakpoint)) ,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.mov32") == 0) { |
cur->func_unit = move; |
set_operand(cur->op1, eval_operand(cur->op2)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.immhi16u") == 0) { |
cur->func_unit = movimm; |
set_operand(cur->op1, (eval_operand(cur->op1) & 0xffff) | (eval_operand(cur->op2) << 16)); |
set_operand(cur->op1, (eval_operand(cur->op1,&breakpoint) & 0xffff) | (eval_operand(cur->op2,&breakpoint) << 16),&breakpoint); |
} else |
|
if (strcmp(cur->insn, "h.add32s") == 0) { |
847,8 → 848,8
signed char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 + temp3; |
CARRY = 0x00000001 & (temp1 >> 32); |
|
860,7 → 861,7
pctemp = 0x0E00; |
} |
else { |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
872,8 → 873,8
signed char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
temp1 = temp2 + temp3 + CARRY; |
CARRY = 0x00000001 & (temp1 >> 32); |
|
885,7 → 886,7
pctemp = 0x0E00; |
} |
else { |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
897,11 → 898,11
unsigned char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
temp1 = temp2 + temp3; |
CARRY = 0x00000001 & (temp1 >> 32); |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
|
temp4 = temp1; |
if (temp4 == temp1) |
913,8 → 914,8
signed char temp4; |
|
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 + temp3; |
CARRY = 0x00000001 & (temp1 >> 32); |
|
925,7 → 926,7
pctemp = 0x0E00; |
} |
else { |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
937,8 → 938,8
signed long long temp1; |
signed char temp4; |
cur->func_unit = arith; |
temp3 = eval_operand(cur->op3); |
temp2 = eval_operand(cur->op2); |
temp3 = eval_operand(cur->op3,&breakpoint); |
temp2 = eval_operand(cur->op2,&breakpoint); |
temp1 = temp2 - temp3; |
CARRY = 0x00000001 & (temp1 >> 32); |
|
950,7 → 951,7
pctemp = 0x0E00; |
} |
else { |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
961,8 → 962,8
signed long long temp1; |
signed char temp4; |
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
temp1 = temp2 - temp3; |
CARRY = 0x00000001 & (temp1 >> 32); |
|
973,7 → 974,7
pctemp = 0x0E00; |
} |
else { |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
984,8 → 985,8
signed long long temp1; |
signed char temp4; |
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
temp1 = temp2 - temp3 - CARRY; |
CARRY = 0x00000001 & (temp1 >> 32); |
|
997,7 → 998,7
pctemp = 0x0E00; |
} |
else { |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
temp4 = temp1; |
if (temp4 == temp1) |
mstats.byteadd++; |
1007,47 → 1008,47
unsigned long long temp3, temp2; |
unsigned long long temp1; |
cur->func_unit = arith; |
temp3 = eval_operand(cur->op2); |
temp2 = eval_operand(cur->op1); |
temp3 = eval_operand(cur->op2,&breakpoint); |
temp2 = eval_operand(cur->op1,&breakpoint); |
temp1 = temp2 - temp3; |
CARRY = 0x00000001 & (temp1 >> 32); |
set_operand(cur->op1, temp1); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
|
if (strcmp(cur->insn, "h.xori16") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) ^ (eval_operand(cur->op3) & 0xffff)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) ^ (eval_operand(cur->op3,&breakpoint) & 0xffff),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.xor32") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op1) ^ eval_operand(cur->op2)); |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) ^ eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.ori16") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) | (eval_operand(cur->op3) & 0xffff)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) | (eval_operand(cur->op3,&breakpoint) & 0xffff),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.or32") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op1) | eval_operand(cur->op2)); |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) | eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.andi16") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op2) & (eval_operand(cur->op3) & 0xffff)); |
set_operand(cur->op1, eval_operand(cur->op2,&breakpoint) & (eval_operand(cur->op3,&breakpoint) & 0xffff),&breakpoint); |
} else |
if (strcmp(cur->insn, "h.and32") == 0) { |
cur->func_unit = arith; |
set_operand(cur->op1, eval_operand(cur->op1) & eval_operand(cur->op2)); |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) & eval_operand(cur->op2,&breakpoint),&breakpoint); |
} else |
|
if (strcmp(cur->insn, "h.shlai32") == 0) { |
signed long temp1; |
cur->func_unit = shift; |
/* debug("shla: op3:%d op4:%d", eval_operand(cur->op3), eval_operand(cur->o |
debug("shla: op4=%s", cur->op4); */ |
/* debug("shla: op3:%d op4:%d", eval_operand(cur->op3,&breakpoint), eval_operand(cur->o |
debug("shla: op4=%s", cur->op4,&breakpoint); */ |
|
temp1 = eval_operand(cur->op1); |
temp1 <<= (0x001f & eval_operand(cur->op2)); |
set_operand(cur->op1, temp1); |
temp1 = eval_operand(cur->op1,&breakpoint); |
temp1 <<= (0x001f & eval_operand(cur->op2,&breakpoint)); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.shrai32") == 0) { |
signed long temp1; |
1056,13 → 1057,13
|
/* operand 1 is to be shifted; operand 2 is shift count */ |
|
temp1 = (signed) eval_operand(cur->op1); |
temp1 >>= (0x001f & eval_operand(cur->op2)); |
set_operand(cur->op1, temp1); |
temp1 = (signed) eval_operand(cur->op1,&breakpoint); |
temp1 >>= (0x001f & eval_operand(cur->op2,&breakpoint)); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.shrli32") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, eval_operand(cur->op1) >> (0x001f & eval_operand(cur->op2)) ); |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) >> (0x001f & eval_operand(cur->op2,&breakpoint)) ,&breakpoint); |
} else |
|
if (strcmp(cur->insn, "h.ror32") == 0) { |
1069,30 → 1070,30
unsigned int temp1, temp2, temp3; |
cur->func_unit = shift; |
|
temp1 = eval_operand(cur->op1); |
temp2 = temp1 >> (0x001f & eval_operand(cur->op2)); |
temp3 = temp1 << (32 - (0x001f & eval_operand(cur->op2))); |
set_operand(cur->op1, temp2 | temp3); |
temp1 = eval_operand(cur->op1,&breakpoint); |
temp2 = temp1 >> (0x001f & eval_operand(cur->op2,&breakpoint)); |
temp3 = temp1 << (32 - (0x001f & eval_operand(cur->op2,&breakpoint))); |
set_operand(cur->op1, temp2 | temp3,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.rol32") == 0) { |
unsigned int temp1, temp2, temp3; |
cur->func_unit = shift; |
|
temp1 = eval_operand(cur->op1); |
temp2 = temp1 << (0x001f & eval_operand(cur->op2)); |
temp3 = temp1 >> (32 - (0x001f & eval_operand(cur->op2))); |
set_operand(cur->op1, temp2 | temp3); |
temp1 = eval_operand(cur->op1,&breakpoint); |
temp2 = temp1 << (0x001f & eval_operand(cur->op2,&breakpoint)); |
temp3 = temp1 >> (32 - (0x001f & eval_operand(cur->op2,&breakpoint))); |
set_operand(cur->op1, temp2 | temp3,&breakpoint); |
} else |
|
if (strcmp(cur->insn, "h.shla32") == 0) { |
signed long temp1; |
cur->func_unit = shift; |
/* debug("shla: op3:%d op4:%d", eval_operand(cur->op3), eval_operand(cur->op4)); |
/* debug("shla: op3:%d op4:%d", eval_operand(cur->op3,&breakpoint), eval_operand(cur->op4,&breakpoint)); |
debug("shla: op4=%s", cur->op4); */ |
|
temp1 = eval_operand(cur->op1); |
temp1 <<= (0x001f & eval_operand(cur->op2)); |
set_operand(cur->op1, temp1); |
temp1 = eval_operand(cur->op1,&breakpoint); |
temp1 <<= (0x001f & eval_operand(cur->op2,&breakpoint)); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.shra32") == 0) { |
signed long temp1; |
1101,18 → 1102,18
|
/* operand 1 is to be shifted; operand 2 is shift count */ |
|
temp1 = (signed) eval_operand(cur->op1); |
temp1 >>= (0x001f & eval_operand(cur->op2)); |
set_operand(cur->op1, temp1); |
temp1 = (signed) eval_operand(cur->op1,&breakpoint); |
temp1 >>= (0x001f & eval_operand(cur->op2,&breakpoint)); |
set_operand(cur->op1, temp1,&breakpoint); |
} else |
if (strcmp(cur->insn, "h.shrl32") == 0) { |
cur->func_unit = shift; |
set_operand(cur->op1, eval_operand(cur->op1) >> (0x001f & eval_operand(cur->op2)) ); |
set_operand(cur->op1, eval_operand(cur->op1,&breakpoint) >> (0x001f & eval_operand(cur->op2,&breakpoint)) ,&breakpoint); |
} else |
|
/* strange insn */ |
if (strcmp(cur->insn, "simrdtsc") == 0) { |
set_operand(cur->op1, cycles); |
set_operand(cur->op1, cycles,&breakpoint); |
} else |
if (strcmp(cur->insn, "simprintf") == 0) { |
unsigned long stackaddr, fmtaddr, args; |
/trunk/or1ksim/cpu/common/parse.h
26,3 → 26,12
#define OPERAND_DELIM "," |
|
extern int nonempty(char *line); |
void adddatastr(char*,int*); |
void adddataword(char*,int*); |
void adddatahalf(char*,int*); |
void adddatabyte(char*,int*); |
void addlabel(char*,unsigned long,int*); |
void addprogram(char*,char*,unsigned int,int*); |
void parseline(char*,int*); |
|
|
/trunk/or1ksim/cpu/common/abstract.c
36,6 → 36,8
#include "sprs.h" |
#include "stats.h" |
#include "except.h" |
#include "debug_unit.h" |
#include "or32.h" |
|
extern unsigned long reg[]; |
|
51,7 → 53,8
{ |
unsigned int i, done = 0; |
struct label_entry *tmp; |
|
int breakpoint = 0; |
|
for(i = from; i < to && i < (MEMORY_START + MEMORY_LEN); i++) { |
if (mem[i].insn) { |
printf("\n%4x:", i); |
66,7 → 69,7
printf("\t%.2x%.2x", mem[i].data, mem[i+1].data); |
printf("%.2x%.2x: ", mem[i+2].data, mem[i+3].data); |
if (mem[i].insn) |
printf("\t%s\t%s", mem[i].insn->insn, mem[i].insn->op1); |
printf("\t%s\t%s", insn_name (mem[i].insn->insn_index), mem[i].insn->op1); |
if (strlen(mem[i].insn->op2)) |
printf("%s%s", OPERAND_DELIM, mem[i].insn->op2); |
if (strlen(mem[i].insn->op3)) |
73,7 → 76,7
printf("%s%s", OPERAND_DELIM, mem[i].insn->op3); |
if (strlen(mem[i].insn->op4)) |
printf("%s%s", OPERAND_DELIM, mem[i].insn->op4); |
i += (insn_len(mem[i].insn->insn) - 1); |
i += insn_len(mem[i].insn->insn_index) - 1; |
} else |
{ |
if (i % 8 == 0) |
97,10 → 100,10
printf("\n%.8x: ", i); |
|
/* don't print ascii chars below 0x20. */ |
if (eval_mem32(i) < 0x20) |
printf("0x%.2x ", (unsigned char)eval_mem32(i)); |
if (eval_mem32(i,&breakpoint) < 0x20) |
printf("0x%.2x ", (unsigned char)eval_mem32(i,&breakpoint)); |
else |
printf("0x%.2x'%c' ", (unsigned char)eval_mem32(i), (unsigned char)eval_mem32(i)); |
printf("0x%.2x'%c' ", (unsigned char)eval_mem32(i,&breakpoint), (unsigned char)eval_mem32(i,&breakpoint)); |
|
} |
} |
253,18 → 256,21
} |
|
/* Returns 32-bit values from mem array. Big endian version. */ |
unsigned long eval_mem32(unsigned long memaddr) |
unsigned long eval_mem32(unsigned long memaddr,int* breakpoint) |
{ |
unsigned long temp; |
struct dev_memarea *dev; |
|
slp_checkaccess(memaddr, SLP_MEMREAD); |
memaddr = simulate_dc_mmu_load(memaddr); |
|
return evalsim_mem32(memaddr); |
unsigned long temp; |
struct dev_memarea *dev; |
|
|
slp_checkaccess(memaddr, SLP_MEMREAD); |
memaddr = simulate_dc_mmu_load(memaddr); |
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */ |
|
return evalsim_mem32(memaddr,breakpoint); |
} |
|
unsigned long evalsim_mem32(unsigned long memaddr) |
unsigned long evalsim_mem32(unsigned long memaddr,int* breakpoint) |
{ |
unsigned long temp; |
struct dev_memarea *dev; |
281,19 → 287,25
cont_run = 0; |
temp = 0; |
} |
|
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* 28/05/01 CZ */ |
|
return temp; |
} |
|
/* Returns 16-bit values from mem array. Big endian version. */ |
|
unsigned short eval_mem16(unsigned long memaddr) |
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint) |
{ |
|
|
memaddr = simulate_dc_mmu_load(memaddr); |
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */ |
|
return evalsim_mem16(memaddr); |
return evalsim_mem16(memaddr,breakpoint); |
} |
|
unsigned short evalsim_mem16(unsigned long memaddr) |
unsigned short evalsim_mem16(unsigned long memaddr,int* breakpoint) |
{ |
unsigned short temp; |
|
305,6 → 317,9
cont_run = 0; |
temp = 0; |
} |
|
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* 28/05/01 CZ */ |
|
return temp; |
} |
|
311,33 → 326,45
|
/* Returns 8-bit values from mem array. */ |
|
unsigned char eval_mem8(unsigned long memaddr) |
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint) |
{ |
|
memaddr = simulate_dc_mmu_load(memaddr); |
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */ |
|
return evalsim_mem8(memaddr); |
return evalsim_mem8(memaddr,breakpoint); |
} |
|
unsigned char evalsim_mem8(unsigned long memaddr) |
unsigned char evalsim_mem8(unsigned long memaddr,int* breakpoint) |
{ |
unsigned char temp; |
|
if (memaddr < (MEMORY_START + MEMORY_LEN)) { |
return (unsigned char)mem[memaddr].data; |
temp = (unsigned char)mem[memaddr].data; |
} else { |
printf("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr); |
cont_run = 0; |
return 0; |
temp = 0; |
} |
|
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* 28/05/01 CZ */ |
|
return temp; |
} |
|
/* Set mem, 32-bit. Big endian version. */ |
|
void set_mem32(unsigned long memaddr, unsigned long value) |
void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint) |
{ |
slp_checkaccess(memaddr, SLP_MEMWRITE); |
memaddr = simulate_dc_mmu_store(memaddr); |
|
setsim_mem32(memaddr, value); |
return; |
slp_checkaccess(memaddr, SLP_MEMWRITE); |
memaddr = simulate_dc_mmu_store(memaddr); |
|
*breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */ |
*breakpoint += CheckDebugUnit(DebugStoreData,value); |
|
setsim_mem32(memaddr, value); |
|
return; |
} |
|
void setsim_mem32(unsigned long memaddr, unsigned long value) |
361,35 → 388,43
|
/* Set mem, 16-bit. Big endian version. */ |
|
void set_mem16(unsigned long memaddr, unsigned short value) |
void set_mem16(unsigned long memaddr, unsigned short value,int* breakpoint) |
{ |
memaddr = simulate_dc_mmu_store(memaddr); |
memaddr = simulate_dc_mmu_store(memaddr); |
|
setsim_mem16(memaddr, value); |
return; |
*breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */ |
*breakpoint += CheckDebugUnit(DebugStoreData,value); |
|
setsim_mem16(memaddr, value); |
|
return; |
} |
|
void setsim_mem16(unsigned long memaddr, unsigned short value) |
{ |
if (memaddr < (MEMORY_START + MEMORY_LEN)) { |
mem[memaddr].data = (value >> 8); |
mem[memaddr + 1].data = (char)(value); |
} else { |
printf("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr); |
cont_run = 0; |
} |
if (memaddr < (MEMORY_START + MEMORY_LEN)) { |
mem[memaddr].data = (value >> 8); |
mem[memaddr + 1].data = (char)(value); |
} else { |
printf("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr); |
cont_run = 0; |
} |
|
return; |
return; |
} |
|
/* Set mem, 8-bit. */ |
|
void set_mem8(unsigned long memaddr, unsigned char value) |
void set_mem8(unsigned long memaddr, unsigned char value,int* breakpoint) |
{ |
memaddr = simulate_dc_mmu_store(memaddr); |
memaddr = simulate_dc_mmu_store(memaddr); |
|
setsim_mem8(memaddr, value); |
return; |
*breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */ |
*breakpoint += CheckDebugUnit(DebugStoreData,value); |
|
setsim_mem8(memaddr, value); |
|
return; |
} |
|
void setsim_mem8(unsigned long memaddr, unsigned char value) |
/trunk/or1ksim/cpu/common/execute.h
21,8 → 21,8
|
#define CURINSN(INSN) (strcmp(cur->insn, (INSN)) == 0) |
|
extern machword eval_operand(char *srcoperand); |
extern void set_operand(char *dstoperand, unsigned long value); |
extern machword eval_operand(char *srcoperand,int* breakpoint); |
extern void set_operand(char *dstoperand, unsigned long value,int* breakpoint); |
extern void dumpreg(); |
extern void set_reg32(char *regstr, unsigned long value); |
|
/trunk/or1ksim/cpu/common/abstract.h
26,66 → 26,67
|
/* Structure for holding several labels of a particular memory location */ |
struct label_entry { |
char *name; |
struct label_entry *next; |
char *name; |
struct label_entry *next; |
}; |
|
/* Structure that holds disassembled instruction. */ |
struct insn_entry { |
char *insn; |
char *op1; |
char *op2; |
char *op3; |
char *op4; |
char *op1; |
char *op2; |
char *op3; |
char *op4; |
/* MM: Instruction index. */ |
int insn_index; |
}; |
|
/* This is an abstract memory type rather than physical memory type. It holds |
disassembled instructions. */ |
struct mem_entry { |
unsigned char data; |
unsigned char brk; |
struct label_entry *label; /* labels */ |
struct insn_entry *insn; /* insn */ |
unsigned char data; |
unsigned char brk; |
struct label_entry *label; /* labels */ |
struct insn_entry *insn; /* insn */ |
}; |
|
enum insn_type { unknown, exception, arith, shift, compare, branch, |
jump, load, store, movimm, move, extend, nop }; |
jump, load, store, movimm, move, extend, nop, mac }; |
|
/* Instruction queue */ |
struct iqueue_entry { |
char insn[INSNAME_LEN]; |
enum insn_type func_unit; |
char op1[OPERANDNAME_LEN]; |
char op2[OPERANDNAME_LEN]; |
char op3[OPERANDNAME_LEN]; |
char op4[OPERANDNAME_LEN]; |
char *dependdst; |
char *dependsrc1; |
char *dependsrc2; |
unsigned long insn_addr; |
enum insn_type func_unit; |
int insn_index; |
char op1[OPERANDNAME_LEN]; |
char op2[OPERANDNAME_LEN]; |
char op3[OPERANDNAME_LEN]; |
char op4[OPERANDNAME_LEN]; |
char *dependdst; |
char *dependsrc1; |
char *dependsrc2; |
unsigned long insn_addr; |
}; |
|
/* Completition queue */ |
struct icomplet_entry { |
char insn[INSNAME_LEN]; |
enum insn_type func_unit; |
char op1[OPERANDNAME_LEN]; |
char op2[OPERANDNAME_LEN]; |
char op3[OPERANDNAME_LEN]; |
char op4[OPERANDNAME_LEN]; |
char *dependdst; |
char *dependsrc1; |
char *dependsrc2; |
unsigned long insn_addr; |
enum insn_type func_unit; |
int insn_index; |
char op1[OPERANDNAME_LEN]; |
char op2[OPERANDNAME_LEN]; |
char op3[OPERANDNAME_LEN]; |
char op4[OPERANDNAME_LEN]; |
char *dependdst; |
char *dependsrc1; |
char *dependsrc2; |
unsigned long insn_addr; |
}; |
|
/* Memory regions assigned to devices */ |
struct dev_memarea { |
struct dev_memarea *next; |
unsigned long baseaddr; |
unsigned long size; |
unsigned char (*readfunc)(unsigned long); |
void (*writefunc)(unsigned long, unsigned char); |
struct dev_memarea *next; |
unsigned long baseaddr; |
unsigned long size; |
unsigned char (*readfunc)(unsigned long); |
void (*writefunc)(unsigned long, unsigned char); |
}; |
|
extern struct iqueue_entry iqueue[20]; |
95,9 → 96,47
extern struct mem_entry mem[MEMORY_LEN]; |
extern void dumpmemory(unsigned int from, unsigned int to); |
extern unsigned long eval_label(char *label); |
extern unsigned long eval_mem32(unsigned long memaddr); |
extern unsigned short eval_mem16(unsigned long memaddr); |
extern unsigned char eval_mem8(unsigned long memaddr); |
extern void set_mem32(unsigned long memaddr, unsigned long value); |
extern void set_mem16(unsigned long memaddr, unsigned short value); |
extern void set_mem8(unsigned long memaddr, unsigned char value); |
extern unsigned long eval_mem32(unsigned long memaddr,int*); |
extern unsigned short eval_mem16(unsigned long memaddr,int*); |
extern unsigned char eval_mem8(unsigned long memaddr,int*); |
extern void set_mem32(unsigned long memaddr, unsigned long value,int*); |
extern void set_mem16(unsigned long memaddr, unsigned short value,int*); |
extern void set_mem8(unsigned long memaddr, unsigned char value,int*); |
|
unsigned long evalsim_mem32(unsigned long,int*); |
unsigned short evalsim_mem16(unsigned long,int*); |
unsigned char evalsim_mem8(unsigned long,int*); |
void setsim_mem32(unsigned long,unsigned long); |
void setsim_mem16(unsigned long,unsigned short); |
void setsim_mem8(unsigned long,unsigned char); |
|
extern int GlobalMode; /* Added by CZ 26/05/01 */ |
|
/* Added by MM */ |
#ifndef LONGEST |
|
#ifdef BFD64 |
|
#define LONGEST BFD_HOST_64_BIT |
#define ULONGEST BFD_HOST_U_64_BIT |
|
#else /* No BFD64 */ |
|
#ifdef CC_HAS_LONG_LONG |
#define LONGEST long long |
#define ULONGEST unsigned long long |
#else |
#ifdef BFD_HOST_64_BIT |
/* BFD_HOST_64_BIT is defined for some hosts that don't have long long |
(e.g. i386-windows) so try it. */ |
#define LONGEST BFD_HOST_64_BIT |
#define ULONGEST BFD_HOST_U_64_BIT |
#else |
#define LONGEST long |
#define ULONGEST unsigned long |
#endif |
#endif |
|
#endif /* No BFD64 */ |
|
#endif /* ! LONGEST */ |
/trunk/or1ksim/cpu/common/parse.c
27,6 → 27,7
#include "arch.h" |
#include "dmmu.h" |
#include "coff.h" |
#include "or32.h" |
|
#define MAXLINE_LEN 18000 |
|
89,7 → 90,7
If loadcode() is called with valid virtphy_transl pointer to a table of |
translations then translate() performs translation otherwise phy address is |
equal to logical. */ |
static unsigned int translate(unsigned int laddr) |
static unsigned int translate(unsigned int laddr,int* breakpoint) |
{ |
int i; |
|
101,23 → 102,23
|
/* Try to find our translation in the table. */ |
for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16) |
if ((laddr & ~(PAGE_SIZE - 1)) == evalsim_mem32(transl_table + i)) { |
if ((laddr & ~(PAGE_SIZE - 1)) == evalsim_mem32(transl_table + i,breakpoint)) { |
setsim_mem32(transl_table + i + 8, -2); /* Page modified */ |
printf("found paddr=%x\n", evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1))); |
return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1)); |
printf("found paddr=%x\n", evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (PAGE_SIZE - 1))); |
return (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (unsigned long)(PAGE_SIZE - 1)); |
} |
|
/* Allocate new phy page for us. */ |
for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16) |
if (evalsim_mem32(transl_table + i + 8) == 0) { |
if (evalsim_mem32(transl_table + i + 8,breakpoint) == 0) { |
setsim_mem32(transl_table + i, laddr & ~(PAGE_SIZE - 1)); /* VPN */ |
setsim_mem32(transl_table + i + 4, (i/16) * PAGE_SIZE); /* PPN */ |
setsim_mem32(transl_table + i + 8, -2); /* Page modified */ |
printf("newly allocated ppn=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4)); |
printf("newly allocated ppn=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint)); |
printf("newly allocated .ppn=%x\n", (unsigned long)transl_table + i + 4); |
printf("newly allocated ofs=%x\n", (unsigned long)(laddr & (PAGE_SIZE - 1))); |
printf("newly allocated paddr=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1))); |
return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1)); |
printf("newly allocated paddr=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (PAGE_SIZE - 1))); |
return (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (unsigned long)(PAGE_SIZE - 1)); |
} |
/* If we come this far then all phy memory is used and we can't find our page |
nor allocate new page. */ |
128,7 → 129,7
return -1; |
} |
|
void adddatastr(char *str) |
void adddatastr(char *str,int* breakpoint) |
{ |
if (str) |
str++; |
135,24 → 136,26
else |
return; |
|
for(; *str && *str != '\"'; str++, translate(freemem++)) |
for(; *str && *str != '\"'; str++, translate(freemem++,breakpoint)) |
if (*str == '\\') |
switch (*++str) { |
case 'n': mem[translate(freemem)].data = '\n'; |
case 'n': mem[translate(freemem,breakpoint)].data = '\n'; |
break; |
case 't': mem[translate(freemem)].data = '\t'; |
case 't': mem[translate(freemem,breakpoint)].data = '\t'; |
break; |
case 'r': mem[translate(freemem)].data = '\r'; |
case 'r': mem[translate(freemem,breakpoint)].data = '\r'; |
break; |
case '0': mem[translate(freemem)].data = '\0'; |
case '0': mem[translate(freemem,breakpoint)].data = '\0'; |
break; |
default: break; |
} |
else |
mem[translate(freemem)].data = *str; |
mem[translate(freemem,breakpoint)].data = *str; |
} |
|
void adddataword(char *item) |
/* Modified by CZ 26/05/01 */ |
/* Added code for new mode operation */ |
void adddataword(char *item,int* breakpoint) |
{ |
unsigned long num; |
|
161,16 → 164,17
else |
num = eval_label(item); |
|
debug("adddataword: [0x%x] <= %x\n", translate(freemem), num); |
mem[translate(freemem)].data = (char) (num >> 24); |
mem[translate(freemem + 1)].data = (char) (num >> 16); |
mem[translate(freemem + 2)].data = (char) (num >> 8); |
mem[translate(freemem + 3)].data = (char) (num); |
debug("adddataword: [0x%x] <= %x\n", translate(freemem,breakpoint), num); |
mem[translate(freemem,breakpoint)].data = (char) (num >> 24); |
mem[translate(freemem + 1,breakpoint)].data = (char) (num >> 16); |
mem[translate(freemem + 2,breakpoint)].data = (char) (num >> 8); |
mem[translate(freemem + 3,breakpoint)].data = (char) (num); |
|
freemem += 4; |
if(!GlobalMode) |
freemem += 4; |
} |
|
void adddatahalf(char *item) |
void adddatahalf(char *item,int* breakpoint) |
{ |
unsigned long num; |
|
179,13 → 183,13
else |
num = eval_label(item); |
|
mem[translate(freemem)].data = (char) (num >> 8); |
mem[translate(freemem + 1)].data = (char) (num); |
mem[translate(freemem,breakpoint)].data = (char) (num >> 8); |
mem[translate(freemem + 1,breakpoint)].data = (char) (num); |
|
freemem += 2; |
} |
|
void adddatabyte(char *item) |
void adddatabyte(char *item,int* breakpoint) |
{ |
unsigned long num; |
|
194,7 → 198,7
else |
num = eval_label(item); |
|
mem[translate(freemem)].data = (char) (num); |
mem[translate(freemem,breakpoint)].data = (char) (num); |
|
freemem++; |
} |
204,12 → 208,12
freemem += atol(num); |
} |
|
void addlabel(char *label, unsigned long freemem) |
void addlabel(char *label, unsigned long freemem,int* breakpoint) |
{ |
struct label_entry **tmp; |
|
debug("Adding label %s at 0x%x\n", label, translate(freemem)); |
tmp = &mem[translate(freemem)].label; |
debug("Adding label %s at 0x%x\n", label, translate(freemem,breakpoint)); |
tmp = &mem[translate(freemem,breakpoint)].label; |
for (; *tmp; tmp = &((*tmp)->next)); |
*tmp = malloc(sizeof(**tmp)); |
(*tmp)->name = malloc(strlen(label)+1); |
221,31 → 225,45
|
char null_str[1] = "\0"; |
|
void addprogram(char *insn, char *operands) |
/* Modified by CZ 26/05/01 */ |
/* Replaced several calls to translate(freemem) with vaddr */ |
/* Added new mode execution code */ |
/* Changed parameters so address can be passed as argument */ |
void addprogram(char *insn, char *operands,unsigned int address,int* breakpoint) |
{ |
int h_insn_is_word_flag=0; |
char insn_first2_char[3]; |
int vaddr = GlobalMode ? translate(address,breakpoint) : translate(freemem,breakpoint); |
|
debug("addprogram 1\n"); |
if (!mem[translate(freemem)].insn) { |
mem[translate(freemem)].insn = malloc(sizeof(*mem[translate(freemem)].insn)); |
mem[translate(freemem)].insn->insn = null_str; |
mem[translate(freemem)].insn->op1 = null_str; |
mem[translate(freemem)].insn->op2 = null_str; |
mem[translate(freemem)].insn->op3 = null_str; |
mem[translate(freemem)].insn->op4 = null_str; |
} else { |
if (!mem[vaddr].insn) { |
mem[vaddr].insn = (struct insn_entry *)malloc (sizeof (struct insn_entry)); |
mem[vaddr].insn->insn_index = -1; |
mem[vaddr].insn->op1 = null_str; |
mem[vaddr].insn->op2 = null_str; |
mem[vaddr].insn->op3 = null_str; |
mem[vaddr].insn->op4 = null_str; |
} else if(!GlobalMode) { /* Old mode */ |
printf("internal error: reloading the same location\n"); |
exit(1); |
} |
} else /* New mode */ |
{ |
if(mem[vaddr].insn->op1 != null_str) free(mem[vaddr].insn->op1); |
if(mem[vaddr].insn->op2 != null_str) free(mem[vaddr].insn->op2); |
if(mem[vaddr].insn->op3 != null_str) free(mem[vaddr].insn->op3); |
if(mem[vaddr].insn->op4 != null_str) free(mem[vaddr].insn->op4); |
mem[vaddr].insn->insn_index = -1; |
mem[vaddr].insn->op1 = null_str; |
mem[vaddr].insn->op2 = null_str; |
mem[vaddr].insn->op3 = null_str; |
mem[vaddr].insn->op4 = null_str; |
} |
|
debug("addprogram 2\n"); |
|
mem[translate(freemem)].insn->insn = malloc(strlen(insn)+1); |
|
#ifdef OR16 |
|
strcpy(mem[translate(freemem)].insn->insn, insn); |
printf("half:%s:\n", insn); |
printf("half:%s:\n", insn); |
insn_first2_char[0]=insn[0]; |
insn_first2_char[1]=insn[1]; |
insn_first2_char[2]='\0'; |
278,14 → 296,15
} |
#else |
debug("addprogram 4\n"); |
strcpy(mem[translate(freemem)].insn->insn, insn); |
debug("addprogram 5\n"); |
#endif |
|
/* MM: added instruction index */ |
mem[vaddr].insn->insn_index = insn_index (insn); |
/* op1 */ |
if (*operands) { |
mem[translate(freemem)].insn->op1 = malloc(strlen(operands)+1); |
strcpy(mem[translate(freemem)].insn->op1, operands); |
mem[vaddr].insn->op1 = malloc(strlen(operands)+1); |
strcpy(mem[vaddr].insn->op1, operands); |
} |
|
debug("addprogram 6\n"); |
292,16 → 311,19
debug("operands:%s\n", operands); |
if (strstr(operands, OPERAND_DELIM)) { |
debug("addprogram 6a\n"); |
operands = strstr(mem[translate(freemem)].insn->op1, OPERAND_DELIM); |
operands = strstr(mem[vaddr].insn->op1, OPERAND_DELIM); |
*operands = '\0'; |
operands++; |
} else { |
debug("addprogram 6b\n"); |
if(!GlobalMode) |
{ |
#ifdef OR16 |
freemem += (h_insn_is_word_flag == 1) ? 2 : 4; |
#else |
freemem += 4; |
#endif |
} |
return; |
} |
|
308,19 → 330,23
debug("addprogram 7\n"); |
/* op2 */ |
if (*operands) { |
mem[translate(freemem)].insn->op2 = malloc(strlen(operands)+1); |
strcpy(mem[translate(freemem)].insn->op2, operands); |
mem[vaddr].insn->op2 = malloc(strlen(operands)+1); |
strcpy(mem[vaddr].insn->op2, operands); |
} |
if (strstr(operands, OPERAND_DELIM)) { |
operands = strstr(mem[translate(freemem)].insn->op2, OPERAND_DELIM); |
operands = strstr(mem[vaddr].insn->op2, OPERAND_DELIM); |
*operands = '\0'; |
operands++; |
} else { |
if(!GlobalMode) |
{ |
#ifdef OR16 |
freemem += (h_insn_is_word_flag == 1) ? 2 : 4; |
#else |
freemem += 4; |
#endif |
} |
|
return; |
} |
|
327,38 → 353,45
debug("addprogram 8\n"); |
/* op3 */ |
if (*operands) { |
mem[translate(freemem)].insn->op3 = malloc(strlen(operands)+1); |
strcpy(mem[translate(freemem)].insn->op3, operands); |
mem[vaddr].insn->op3 = malloc(strlen(operands)+1); |
strcpy(mem[vaddr].insn->op3, operands); |
} |
if (strstr(operands, OPERAND_DELIM)) { |
operands = strstr(mem[translate(freemem)].insn->op3, OPERAND_DELIM); |
operands = strstr(mem[vaddr].insn->op3, OPERAND_DELIM); |
*operands = '\0'; |
operands++; |
} else { |
if(!GlobalMode) |
{ |
#ifdef OR16 |
freemem += (h_insn_is_word_flag == 1) ? 2 : 4; |
#else |
freemem += 4; |
#endif |
} |
return; |
} |
|
/* op4 */ |
if (*operands) { |
mem[translate(freemem)].insn->op4 = malloc(strlen(operands)+1); |
strcpy(mem[translate(freemem)].insn->op4, operands); |
mem[vaddr].insn->op4 = malloc(strlen(operands)+1); |
strcpy(mem[vaddr].insn->op4, operands); |
} |
if (strstr(operands, OPERAND_DELIM)) { |
operands = strstr(mem[translate(freemem)].insn->op4, OPERAND_DELIM); |
operands = strstr(mem[vaddr].insn->op4, OPERAND_DELIM); |
*operands = '\0'; |
operands++; |
} |
|
if(!GlobalMode) |
{ |
#ifdef OR16 |
freemem += (h_insn_is_word_flag == 1) ? 2 : 4; |
#else |
freemem += 4; |
#endif |
} |
|
return; |
} |
|
365,7 → 398,7
/* Non-architecture dependent parsing: stripping comments, filling |
abstract memory */ |
|
void parseline(char *inputline) |
void parseline(char *inputline,int* breakpoint) |
{ |
char item[MAXLINE_LEN]; |
char item2[MAXLINE_LEN]; |
393,7 → 426,7
/* Is this item a label? If yes, add it to the label table and return immediately. */ |
if (strstr(item, LABELEND_CHAR)) { |
*strstr(item, LABELEND_CHAR) = '\0'; |
addlabel(item, translate(freemem)); |
addlabel(item, translate(freemem,breakpoint),breakpoint); |
return; |
} |
|
402,7 → 435,7
if (item[0] == DIRECTIVE_CHAR) { |
if (strcmp(item, ".align") == 0) { |
int align = strtoul(item2, NULL, 0); |
if (!(translate(freemem) % align)) |
if (!(translate(freemem,breakpoint) % align)) |
return; |
freemem &= -align; |
freemem += align; |
414,19 → 447,19
return; |
} else |
if (strcmp(item, ".ascii") == 0) { |
adddatastr(strstr(inputline, "\"")); |
adddatastr(strstr(inputline, "\""),breakpoint); |
return; |
} else |
if (strcmp(item, ".word") == 0) { |
adddataword(item2); |
adddataword(item2,breakpoint); |
return; |
} else |
if (strcmp(item, ".half") == 0) { |
adddatahalf(item2); |
adddatahalf(item2,breakpoint); |
return; |
} else |
if (strcmp(item, ".byte") == 0) { |
adddatabyte(item2); |
adddatabyte(item2,breakpoint); |
return; |
} else |
if (strcmp(item, ".space") == 0) { |
438,8 → 471,8
|
/* This item can only be an instruction. Get all operands |
and add everything to mem array but as a program. */ |
debug("%x: ", translate(freemem)); |
addprogram(item, item2); |
debug("%x: ", translate(freemem,breakpoint)); |
addprogram(item, item2,freemem,breakpoint); |
|
/* Also do static, single stats. */ |
addsstats(item, 0, 1); |
462,7 → 495,8
char item[MAXLINE_LEN]; |
char item2[MAXLINE_LEN]; |
int firstthree = 0; |
|
int breakpoint = 0; |
|
if (!(inputfs = fopen(filename, "r"))) { |
perror("readfile_coff"); |
exit(1); |
500,12 → 534,12
|
sectsize = COFF_LONG_H(coffscnhdr.s_size); |
/* A couple of sanity checks. */ |
if (translate(COFF_LONG_H(coffscnhdr.s_vaddr)) < MEMORY_START) { |
if (translate(COFF_LONG_H(coffscnhdr.s_vaddr),&breakpoint) < MEMORY_START) { |
printf("Section %s starts out of ", coffscnhdr.s_name); |
printf("memory (at %x)\n", COFF_LONG_H(coffscnhdr.s_vaddr)); |
exit(1); |
} |
if (translate(COFF_LONG_H(coffscnhdr.s_vaddr) + sectsize) > |
if (translate(COFF_LONG_H(coffscnhdr.s_vaddr) + sectsize,&breakpoint) > |
MEMORY_START + MEMORY_LEN) { |
printf("Section %s ends out of ", coffscnhdr.s_name); |
printf("memory.\n"); |
536,7 → 570,7
insn = COFF_LONG_H(inputbuf); |
len = disassemble_insn(insn); |
sprintf(item, "%u", insn); |
adddataword(item); |
adddataword(item,&breakpoint); |
freemem -= len; |
if (len == 2) { |
fseek(inputfs, -2, SEEK_CUR); |
547,7 → 581,7
debug("%s\n", disassembled); |
strtoken(disassembled, item, 1); /* opcode */ |
strtoken(disassembled, item2, 2); /* all the remaining one/two/three operands */ |
addprogram(item, item2); |
addprogram(item, item2,freemem,&breakpoint); |
sectsize -= len; |
} |
} |
572,7 → 606,7
{ |
FILE *inputfs; |
struct COFF_syment coffsymhdr; |
|
int breakpoint = 0; |
|
if (!(inputfs = fopen(filename, "r"))) { |
perror("readsyms_coff"); |
595,7 → 629,7
debug(" val: 0x%.8x,", COFF_LONG_H(coffsymhdr.e_value)); |
debug(" auxs: %c\n", coffsymhdr.e_numaux); |
if (strlen(coffsymhdr.e.e_name) && strlen(coffsymhdr.e.e_name) < 9) |
addlabel(coffsymhdr.e.e_name, COFF_LONG_H(coffsymhdr.e_value)); |
addlabel(coffsymhdr.e.e_name, COFF_LONG_H(coffsymhdr.e_value),&breakpoint); |
} |
|
fclose(inputfs); |
610,7 → 644,8
FILE *inputfs; |
char inputbuf[MAXLINE_LEN]; |
char *status; |
|
int breakpoint = 0; |
|
if (!(inputfs = fopen(filename, "r"))) { |
perror("readfile_assembly"); |
exit(1); |
618,7 → 653,7
|
while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) { |
if (nonempty(inputbuf)) |
parseline(inputbuf); |
parseline(inputbuf,&breakpoint); |
} |
fclose(inputfs); |
|
684,6 → 719,8
/* Loads file to memory starting at address startaddr and returns freemem. */ |
unsigned long loadcode(char *filename, unsigned long startaddr, unsigned long virtphy_transl) |
{ |
int breakpoint = 0; |
|
transl_error = 0; |
transl_table = virtphy_transl; |
freemem = startaddr; |
692,5 → 729,5
if (transl_error) |
return -1; |
else |
return translate(freemem); |
return translate(freemem,&breakpoint); |
} |
/trunk/or1ksim/cpu/or1k/Makefile.in
105,7 → 105,7
host_os = @host_os@ |
|
noinst_LIBRARIES = libor1k.a |
libor1k_a_SOURCES = sprs.c decode.c except.c |
libor1k_a_SOURCES = sprs.c decode.c except.c or32.c |
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs |
CONFIG_HEADER = ../../config.h |
CONFIG_CLEAN_FILES = |
117,7 → 117,7
LDFLAGS = @LDFLAGS@ |
LIBS = @LIBS@ |
libor1k_a_LIBADD = |
libor1k_a_OBJECTS = sprs.o decode.o except.o |
libor1k_a_OBJECTS = sprs.o decode.o except.o or32.o |
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
CCLD = $(CC) |
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ |
128,7 → 128,7
|
TAR = gtar |
GZIP_ENV = --best |
DEP_FILES = .deps/decode.P .deps/except.P .deps/sprs.P |
DEP_FILES = .deps/decode.P .deps/except.P .deps/or32.P .deps/sprs.P |
SOURCES = $(libor1k_a_SOURCES) |
OBJECTS = $(libor1k_a_OBJECTS) |
|
/trunk/or1ksim/cpu/or1k/sprs.c
28,6 → 28,8
|
static sprword sprs[MAX_SPRS]; |
|
int temp_disable_except = 0; |
|
/* Set a specific SPR with a value. */ |
void mtspr(int regno, sprword value) |
{ |
58,6 → 60,11
regno /= MAX_SPRS_PER_GRP; |
regno += ofs; |
|
/* MM: l.rfe, for example, temporarly disables |
exceptions. We will make it appear as SR bit |
is set. */ |
/*if (regno == SPR_SR && temp_disable_except > 0) |
return sprs[regno] | SPR_SR_EXR;*/ |
/* printf("mfspr(%x)%x\n", regno, sprs[regno]); |
*/ if (regno < MAX_SPRS) |
return sprs[regno]; |
/trunk/or1ksim/cpu/or1k/Makefile.am
19,5 → 19,5
# |
|
noinst_LIBRARIES = libor1k.a |
libor1k_a_SOURCES = sprs.c decode.c except.c |
libor1k_a_SOURCES = sprs.c decode.c except.c or32.c |
|
/trunk/or1ksim/cpu/or1k/except.c
29,9 → 29,11
extern struct iqueue_entry iqueue[20]; |
extern unsigned long pc; |
extern unsigned long pcnext; |
extern unsigned long pc_phy; |
extern struct iqueue_entry iqueue[]; |
|
extern int delay_insn; |
int cycle_delay = 0; /* Added by CZ 27/05/01 */ |
|
/* Handle OR1K exceptions. */ |
void except_handle(int except, unsigned long ea) |
65,7 → 67,7
cont_run = 0; |
return; |
} |
|
|
pc_saved = pc & ~0x3; |
mtspr(SPR_EPCR_BASE, pc_saved); |
mtspr(SPR_EEAR_BASE, ea); |
78,6 → 80,16
mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_SUPV); /* SUPV mode */ |
mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_EXR); /* Disable except. */ |
pc = (unsigned long)except; |
pcnext = (unsigned long)except; |
|
/* MM: We do pc update after the execute (in the simulator), so we |
decrease it by 4 so that next instruction points to first exception |
instruction. */ |
if (except == EXCEPT_SYSCALL) |
pc -= 4; |
pcnext = pc+4; |
|
/* Added by CZ 27/05/01 */ |
pc_phy = pc; |
cycle_delay = 7; /* An exception stalls the CPU 7 clock cycles */ |
#endif |
} |
/trunk/or1ksim/cpu/or1k/sprs.h
28,3 → 28,5
int getsprbit(int regno, int bitnum); |
void sprs_status(); |
|
/* MM: If set, disables exceptions for temp_disable_except cycles. */ |
extern int temp_disable_except; |
/trunk/or1ksim/tick/Makefile
77,15 → 77,15
NORMAL_UNINSTALL = : |
PRE_UNINSTALL = : |
POST_UNINSTALL = : |
build_alias = i586-pc-linux-gnu |
build_triplet = i586-pc-linux-gnu |
host_alias = i586-pc-linux-gnu |
host_triplet = i586-pc-linux-gnu |
build_alias = i686-pc-linux-gnu |
build_triplet = i686-pc-linux-gnu |
host_alias = i686-pc-linux-gnu |
host_triplet = i686-pc-linux-gnu |
target_alias = or32 |
target_triplet = or32-unknown-none |
AR = ar |
ARFLAGS = cr |
BUILD_DIR = /root/or1k/or1ksim |
BUILD_DIR = /projects/or1k/src/sim1 |
CC = gcc |
CFLAGS = -g -O2 -DOR32 |
CPU_ARCH = or32 |
100,8 → 100,8
SUMVERSION = |
TERMCAP_LIB = |
VERSION = 1.3 |
host = i586-pc-linux-gnu |
host_cpu = i586 |
host = i686-pc-linux-gnu |
host_cpu = i686 |
host_os = linux-gnu |
|
noinst_LIBRARIES = libtick.a |
/trunk/or1ksim/peripheral/16450.c
183,25 → 183,29
space. */ |
void uart_reset() |
{ |
int i; |
|
printf("Resetting %u UART(s).\n", NR_UARTS); |
memset(uarts, 0, sizeof(uarts)); |
|
for(i = 0; i < NR_UARTS; i++) |
if (config.uarts[i].txfile) { |
uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r"); |
uarts[i].txfs = fopen(config.uarts[i].txfile, "a"); |
uarts[i].baseaddr = config.uarts[i].baseaddr; |
if (uarts[i].txfs) { |
printf("UART%d at 0x%.8x uses ", i, uarts[i].baseaddr); |
printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile, config.uarts[i].txfile); |
} else |
printf("UART%d has problems with TX file stream.\n", i); |
register_memoryarea(uarts[i].baseaddr, UART_ADDR_SPACE, uart_read, uart_write); |
} |
int i; |
|
printf("Resetting %u UART(s).\n", NR_UARTS); |
memset(uarts, 0, sizeof(uarts)); |
|
for(i = 0; i < NR_UARTS; i++) |
if (config.uarts[i].txfile) { /* MM: Try to create stream. */ |
if (!(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r")) |
&& !(uarts[i].rxfs = fopen(config.uarts[i].rxfile, "r+"))) { |
printf("UART%d has problems with RX file stream.\n", i); |
continue; |
} |
uarts[i].txfs = fopen(config.uarts[i].txfile, "a"); |
uarts[i].baseaddr = config.uarts[i].baseaddr; |
if (uarts[i].txfs && uarts[i].txfs) { |
printf("UART%d at 0x%.8x uses ", i, uarts[i].baseaddr); |
printf("%s for RX and %s for TX.\n", config.uarts[i].rxfile, config.uarts[i].txfile); |
} else |
printf("UART%d has problems with TX file stream.\n", i); |
register_memoryarea(uarts[i].baseaddr, UART_ADDR_SPACE, uart_read, uart_write); |
} |
} |
|
|
/* Simulation hook. Must be called every clock cycle to simulate all UART |
devices. It does internal functional UART simulation. */ |
void uart_clock() |
/trunk/or1ksim/peripheral/Makefile.in
105,7 → 105,7
host_os = @host_os@ |
|
noinst_LIBRARIES = libperipheral.a |
libperipheral_a_SOURCES = 16450.c |
libperipheral_a_SOURCES = 16450.c debug_unit.c |
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs |
CONFIG_HEADER = ../config.h |
CONFIG_CLEAN_FILES = |
117,7 → 117,7
LDFLAGS = @LDFLAGS@ |
LIBS = @LIBS@ |
libperipheral_a_LIBADD = |
libperipheral_a_OBJECTS = 16450.o |
libperipheral_a_OBJECTS = 16450.o debug_unit.o |
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
CCLD = $(CC) |
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ |
128,7 → 128,7
|
TAR = gtar |
GZIP_ENV = --best |
DEP_FILES = .deps/16450.P |
DEP_FILES = .deps/16450.P .deps/debug_unit.P |
SOURCES = $(libperipheral_a_SOURCES) |
OBJECTS = $(libperipheral_a_OBJECTS) |
|
/trunk/or1ksim/peripheral/Makefile.am
19,4 → 19,4
# |
|
noinst_LIBRARIES = libperipheral.a |
libperipheral_a_SOURCES = 16450.c |
libperipheral_a_SOURCES = 16450.c debug_unit.c |
/trunk/or1ksim/config.h.in
19,6 → 19,8
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */ |
#undef STAT_MACROS_BROKEN |
|
#define HAS_EXECUTION |
|
/* Define if you have the lstat function. */ |
#undef HAVE_LSTAT |
|
/trunk/or1ksim/Makefile.am
13,4 → 13,4
cpu/or1k/libor1k.a support/libsupport.a mmu/libmmu.a \ |
bpb/libbpb.a cache/libcache.a peripheral/libperipheral.a \ |
tick/libtick.a pm/libpm.a pic/libpic.a |
sim_LDFLAGS = -lreadline |
sim_LDFLAGS = #-lreadline |
/trunk/or1ksim/pic/pic.c
49,13 → 49,24
|
picsr = mfspr(SPR_PICSR); |
picpr = mfspr(SPR_PICPR); |
|
if (picsr & picpr) { |
|
/* SIMON: This is a bug */ |
/* if (picsr & picpr) { |
if ((mfspr(SPR_SR) & (SPR_SR_EIR | SPR_SR_EXR)) == (SPR_SR_EIR | SPR_SR_EXR)) |
except_handle(EXCEPT_HPINT, 0); |
} else |
if ((mfspr(SPR_SR) & (SPR_SR_EIR | SPR_SR_EXR)) == (SPR_SR_EIR | SPR_SR_EXR)) |
except_handle(EXCEPT_LPINT, 0); |
*/ |
if ((mfspr(SPR_SR) & (SPR_SR_EIR | SPR_SR_EXR)) == (SPR_SR_EIR | SPR_SR_EXR)) { |
picsr = mfspr(SPR_PICSR); |
picpr = mfspr(SPR_PICPR); |
if (picsr & picpr) { |
except_handle(EXCEPT_HPINT, 0); |
} else if(picsr) { |
except_handle(EXCEPT_LPINT, 0); |
} |
} |
} |
|
/* Asserts interrupt to the PIC. */ |
/trunk/or1ksim/toplevel.c
29,6 → 29,16
#include <unistd.h> |
#include <signal.h> |
#include <stdarg.h> |
/* Added by CZ 24/05/01 */ |
#include <sys/stat.h> |
#include <sys/types.h> |
#include <sys/socket.h> |
#include <netinet/in.h> |
#include <sys/select.h> |
#include <sys/poll.h> |
#include <fcntl.h> |
#include <netdb.h> |
#include <netinet/tcp.h> |
|
#ifdef HAVE_LIBREADLINE |
#include <readline/readline.h> |
45,8 → 55,24
|
#include "coff.h" |
|
/* Added by CZ 24/05/01 */ |
#include <signal.h> |
#include <errno.h> |
typedef enum { |
false = 0, |
true = 1, |
} Boolean; |
unsigned int serverIP = 0; |
unsigned int serverPort = 0; |
unsigned int server_fd = 0; |
unsigned int gdb_fd = 0; |
void HandleServerSocket(Boolean); |
void JTAGRequest(void); |
void GDBRequest(void); |
int GlobalMode = 0; /* Start off in the orginal mode */ |
|
/* CVS revision number. */ |
const char rcsrev[] = "$Revision: 1.15 $"; |
const char rcsrev[] = "$Revision: 1.16 $"; |
|
/* Continuos run versus single step tracing switch. */ |
int cont_run; |
134,6 → 160,7
int signum; |
{ |
cont_run = 1; |
config.iprompt = 1; |
signal(SIGINT, ctrl_c); |
} |
|
188,11 → 215,12
char item1[500], b2[500]; |
char *redirstr; |
int hush; |
unsigned long endaddr; |
|
unsigned long endaddr = 0xFFFFFFFF; |
int first_prompt = 1; |
|
srand(getpid()); |
init_defconfig(); |
if ((argc < 2) || parse_args(argc, argv)) { |
if (parse_args(argc, argv)) { |
printf("Usage: %s [options] <filename>\n", argv[0]); |
printf("Options:\n"); |
printf(" -v: version and copyright note\n"); |
202,10 → 230,17
printf(" -hazards: disable dependency hazards analysis\n"); |
printf(" -history: disable instruction stream history analysis\n"); |
printf(" -superscalar: disable superscalar analysis\n"); |
printf(" -fast: disable BPB, BTIC, SLP, dependency hazards, history analysis etc.\n"); |
printf(" -fast: disable BPB, BTIC, SLP, dependency hazards, history" |
" analysis etc.\n"); |
printf(" -upr <n>: set UPR to n\n"); |
printf(" -ver <n>: set VR[VER] to n\n"); |
printf(" -rev <n>: set VR[REV] to n\n"); |
printf(" -loadmem[@<n>] <filename>: load memory with file, " |
"optionally at address <n>\n"); /* (CZ) */ |
printf(" -nosrv: do not launch JTAG proxy server\n"); /* (CZ) */ |
printf(" -srv <n>: launch JTAG proxy server on port <n>\n"); /* (CZ) */ |
printf(" -initmem <n | random>: initialize memory to value " |
"<n> or random\n"); /* (CZ) */ |
exit(-1); |
} |
|
212,30 → 247,158
#ifdef HAVE_LIBREADLINE |
initialize_readline (); /* Bind our completer. */ |
#endif |
|
if(!config.inhibit_server) |
{ |
serverPort = config.server_port; |
if(server_fd = GetServerSocket("or1ksim","tcp",serverPort)) |
printf("JTAG Proxy server started on port %d\n",serverPort); |
} |
|
print_config(); |
signal(SIGINT, ctrl_c); |
initstats(); |
memset(mem, 0, sizeof(mem)); |
endaddr = loadcode(argv[argc-1], MEMORY_START, 0); |
if (endaddr == -1) { |
printf("Problems loading boot code.\n"); |
exit(1); |
} |
|
/* Modified by CZ on 24/05/01 ... if a filename is |
specified, behave as the simulator always has. This way, |
no existing test suites should be broken. If a filename |
is not specified, default to the new style behavior. Let |
the simulator start up and execute garbage, the same way |
a real CPU would. This should maximize the reality of |
the capabilities. In this mode, we will expect that |
someone will attach to us over the JTAG Proxy interface |
and begin debugging that way. */ |
|
if(config.filename) |
{ |
endaddr = loadcode(config.filename, MEMORY_START, 0); |
if (endaddr == -1) { |
printf("Problems loading boot code.\n"); |
exit(1); |
} |
} |
else |
{ |
if(config.random_mem) |
{ |
int n = 0; |
int len = sizeof(mem); |
unsigned int* mptr = (unsigned int*)mem; |
unsigned int val = 0; |
int seed = time(NULL); |
|
srandom(seed); |
/* Print out the seed just in case we ever need to debug */ |
printf("Seeding random generator with value %d\n",seed); |
|
for(n=0;n<len;n+=sizeof(unsigned int)) |
{ |
val = random(); |
if(random() > RAND_MAX/2) |
val |= 0x80000000; |
*mptr++ = val; |
} |
} |
else if(config.pattern_mem) |
{ |
int n = 0; |
int len = sizeof(mem); |
unsigned int* mptr = (unsigned int*)mem; |
|
for(n=0;n<len;n+=sizeof(unsigned int)) |
*mptr++ = config.pattern_mem; |
} |
else |
memset(mem,0,sizeof(mem)); |
|
if(config.memory) |
{ |
MemoryBlock* block = config.memory; |
|
while(block) |
{ |
int fd = open(block->file,O_RDONLY); |
int len,i; |
struct stat buf; |
char *mptr = (char*)mem; |
char buffer[8192]; |
|
if(fd < 0) |
{ |
perror(block->file); |
exit(1); |
} |
if(fstat(fd,&buf) < 0) |
{ |
char sTemp[256]; |
|
sprintf(sTemp,"stat(\"%s\")",block->file); |
perror(sTemp); |
exit(1); |
} |
if(!S_ISREG(buf.st_mode)) |
{ |
fprintf(stderr,"File \"%s\" is not a regular file.\n", |
block->file); |
exit(1); |
} |
|
len = buf.st_size; |
mptr += block->address; |
for(i=0;i<len;) |
{ |
int n = read(fd,buffer,sizeof(buffer)); |
|
switch(n) |
{ |
case -1: |
if(errno == EINTR) |
continue; |
perror(block->file); |
exit(1); |
case 0: |
fprintf(stderr,"File \"%s\": premature end of file.\n", |
block->file); |
exit(1); |
default: |
memcpy(mptr,buffer,n); |
i+= n; |
break; |
} |
} |
close(fd); |
} |
} |
} |
GlobalMode = config.filename == NULL; /* Old mode = 0, New mode = 1 */ |
|
uart_reset(); |
tick_reset(); |
pm_reset(); |
pic_reset(); |
reset(); |
set_reg32("r3", endaddr); |
if(!GlobalMode) /* Only in old mode */ |
set_reg32("r3", endaddr); |
|
while(1) { |
if (config.iprompt) { |
if(server_fd) |
{ |
printf ("(sim) "); |
fflush(stdout); |
HandleServerSocket(true); /* block & check_stdin = true */ |
} |
#ifdef HAVE_LIBREADLINE |
linestr = readline("(sim) "); |
/* Must disable readline in new mode. It isn't compatible |
with non blocking environments */ |
if(!server_fd) |
linestr = readline("(sim) "); |
else |
linestr = fgets(b2, sizeof b2, stdin); |
#else |
printf ("(sim) "); |
linestr = fgets(b2, sizeof b2, stdin); |
if(!server_fd) |
printf ("(sim) "); |
linestr = fgets(b2, sizeof b2, stdin); |
#endif |
} else |
strcpy(linestr = b2, "run 100000000 hush"); |
245,18 → 408,22
linestr = stripwhite (linestr); |
|
#ifdef HAVE_LIBREADLINE |
if (strlen(linestr) == 0) { |
char *l = repeat_last_command (); |
|
if (l) { |
free (linestr); |
linestr = l; |
} |
} |
|
if (*linestr) { |
add_history (linestr); |
} |
/* Readline only works in the old mode */ |
if(!server_fd) |
{ |
if (strlen(linestr) == 0) { |
char *l = repeat_last_command (); |
|
if (l) { |
free (linestr); |
linestr = l; |
} |
} |
|
if (*linestr) { |
add_history (linestr); |
} |
} |
#endif /* HAVE_LIBREADLINE */ |
|
if (redirstr = strstr(linestr, ">")) { |
343,7 → 510,8
char item2[20]; |
char item3[20]; |
static int addr = 0; |
|
int breakpoint = 0; |
|
strtoken(linestr, item2, 2); |
strtoken(linestr, item3, 3); |
if (strlen(item2)) |
351,7 → 519,7
addr = eval_label(item2); |
else |
addr = strtoul(item2, NULL, 0); |
set_mem32(addr, strtoul(item3, NULL, 0)); |
set_mem32(addr, strtoul(item3, NULL, 0), &breakpoint); |
} else |
if (strcmp(item1, "pr") == 0) { /* patch regs */ |
char item2[20]; |
384,7 → 552,7
tick_reset(); |
pm_reset(); |
pic_reset(); |
reset(); |
reset(); /* Old or new mode */ |
} else |
if (strcmp(item1, "debug") == 0) { /* debug mode */ |
config.simdebug ^= 1; |
434,28 → 602,40
} |
|
while(cont_run) { |
cont_run--; |
extern int cycle_delay; /* Added by CZ 27/05/01. Set during exception. */ |
|
if (!getsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) { |
fetch(); |
decode_execute(&iqueue[0]); |
analysis(); |
if (!hush) |
dumpreg(); |
pic_clock(); |
dc_clock(); |
ic_clock(); |
if(cycle_delay <= 0) |
{ |
cont_run--; |
if(fetch()) { |
cont_run = 0; /* memory breakpoint encountered */ |
break; |
} |
decode_execute(&iqueue[0]); |
update_pc(); |
analysis(); |
if (!hush) |
dumpreg(); |
} |
else |
cycle_delay--; |
|
pic_clock(); |
dc_clock(); |
ic_clock(); |
} |
if (!getsprbits(SPR_PMR, SPR_PMR_SME)) |
tick_clock(); |
tick_clock(); |
pm_clock(); |
uart_clock(); |
HandleServerSocket(false); /* block & check_stdin = false */ |
} |
|
hush = 0; |
fflush(stdout); |
freopen("/dev/fd/0", "w+", stdout); |
|
if (!config.iprompt) /* non-interactive quit */ |
if (!config.iprompt && !GlobalMode) /* non-interactive quit in old mode */ |
exit(0); |
|
#ifdef HAVE_LIBREADLINE |
574,7 → 754,7
printf("i=%x :: ", i); |
if (mem[i].label) |
printf("label: %s |", mem[i].label->name); |
printf("%s ", mem[i].insn->insn); |
printf("%s ", insn_name (mem[i].insn->insn_index)); |
if(strlen(mem[i].insn->op1) != 0) printf("%s ", mem[i].insn->op1); |
if(strlen(mem[i].insn->op2) != 0) printf("%s ", mem[i].insn->op2); |
if(strlen(mem[i].insn->op3) != 0) printf("%s ", mem[i].insn->op3); |
582,3 → 762,255
printf("\n"); |
} |
} |
|
/* Added by CZ 24/05/01 */ |
int GetServerSocket(const char* name,const char* proto,int port) |
{ |
struct servent *service; |
struct protoent *protocol; |
struct sockaddr_in sa; |
struct hostent *hp; |
int sockfd; |
char myname[256]; |
int flags; |
char sTemp[256]; |
|
/* First, get the protocol number of TCP */ |
if(!(protocol = getprotobyname(proto))) |
{ |
sprintf(sTemp,"Unable to load protocol \"%s\"",proto); |
perror(sTemp); |
return 0; |
} |
|
/* If we weren't passed a non standard port, get the port |
from the services directory. */ |
if(!port) |
{ |
if(service = getservbyname(name,protocol->p_name)) |
port = ntohs(service->s_port); |
} |
|
/* Create the socket using the TCP protocol */ |
if((sockfd = socket(PF_INET,SOCK_STREAM,protocol->p_proto)) < 0) |
{ |
perror("Unable to create socket"); |
return 0; |
} |
|
flags = 1; |
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const char*)&flags,sizeof(int)) |
< 0) |
{ |
sprintf(sTemp,"Can not set SO_REUSEADDR option on socket %d",sockfd); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
|
/* The server should also be non blocking. Get the current flags. */ |
if(fcntl(sockfd,F_GETFL,&flags) < 0) |
{ |
sprintf(sTemp,"Unable to get flags for socket %d",sockfd); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
|
/* Set the nonblocking flag */ |
if(fcntl(sockfd,F_SETFL, flags | O_NONBLOCK) < 0) |
{ |
sprintf(sTemp,"Unable to set flags for socket %d to value 0x%08x", |
sockfd,flags | O_NONBLOCK); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
|
/* Find out what our address is */ |
memset(&sa,0,sizeof(struct sockaddr_in)); |
gethostname(myname,sizeof(myname)); |
if(!(hp = gethostbyname(myname))) |
{ |
perror("Unable to read hostname"); |
close(sockfd); |
return 0; |
} |
|
/* Bind our socket to the appropriate address */ |
sa.sin_family = hp->h_addrtype; |
sa.sin_port = htons(port); |
if(bind(sockfd,(struct sockaddr*)&sa,sizeof(struct sockaddr_in)) < 0) |
{ |
sprintf(sTemp,"Unable to bind socket %d to port %d",sockfd,port); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
serverIP = sa.sin_addr.s_addr; |
flags = sizeof(struct sockaddr_in); |
if(getsockname(sockfd,(struct sockaddr*)&sa,&flags) < 0) |
{ |
sprintf(sTemp,"Unable to get socket information for socket %d",sockfd); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
serverPort = ntohs(sa.sin_port); |
|
/* Set the backlog to 1 connections */ |
if(listen(sockfd,1) < 0) |
{ |
sprintf(sTemp,"Unable to set backlog on socket %d to %d",sockfd,1); |
perror(sTemp); |
close(sockfd); |
return 0; |
} |
|
return sockfd; |
} |
|
void HandleServerSocket(Boolean block) |
{ |
struct pollfd fds[2]; |
int n = 0; |
int timeout = block ? -1 : 0; |
int server_index = -1; |
int gdb_index = -1; |
Boolean data_on_stdin = false; |
int o_serv_fd = server_fd; |
|
if(!o_serv_fd && !gdb_fd) |
return; |
|
if(o_serv_fd) |
{ |
fds[n].fd = o_serv_fd; |
fds[n].events = POLLIN; |
fds[n++].revents = 0; |
} |
if(gdb_fd) |
{ |
fds[n].fd = gdb_fd; |
fds[n].events = POLLIN; |
fds[n++].revents = 0; |
} |
if(block) |
{ |
fds[n].fd = 0; |
fds[n].events = POLLIN; |
fds[n++].revents = 0; |
} |
|
while(!data_on_stdin) |
{ |
switch(poll(fds,n,timeout)) |
{ |
case -1: |
if(errno == EINTR) |
continue; |
perror("poll"); |
server_fd = 0; |
break; |
case 0: /* Nothing interesting going on */ |
data_on_stdin = true; /* Can only get here if nonblocking */ |
break; |
default: |
if(fds[0].revents && o_serv_fd) |
{ |
if(fds[0].revents & POLLIN) |
JTAGRequest(); |
else /* Error Occurred */ |
{ |
fprintf(stderr,"Received flags 0x%08x on server. Shutting down.\n",fds[0].revents); |
close(o_serv_fd); |
server_fd = 0; |
serverPort = 0; |
serverIP = 0; |
} |
} |
if((fds[0].revents && (gdb_fd && !o_serv_fd) || |
fds[1].revents && (server_fd && gdb_fd))) |
{ |
int revents = o_serv_fd ? fds[1].revents : fds[0].revents; |
|
if(revents & POLLIN) |
GDBRequest(); |
else /* Error Occurred */ |
{ |
fprintf(stderr,"Received flags 0x%08x on gdb socket. Shutting down.\n",revents); |
close(gdb_fd); |
gdb_fd = 0; |
} |
} |
if(fds[2].revents || (fds[1].revents && !gdb_fd)) |
data_on_stdin = true; |
break; |
} /* End of switch statement */ |
} /* End of while statement */ |
} |
|
void JTAGRequest() |
{ |
struct sockaddr_in sa; |
struct sockaddr* addr = (struct sockaddr*)&sa; |
int n = sizeof(struct sockaddr_in); |
int fd = accept(server_fd,addr,&n); |
int on_off = 0; /* Turn off Nagel's algorithm on the socket */ |
int flags; |
char sTemp[256]; |
|
if(fd < 0) |
{ |
/* This is valid, because a connection could have started, |
and then terminated due to a protocol error or user |
initiation before the accept could take place. */ |
if(errno != EWOULDBLOCK && errno != EAGAIN) |
{ |
perror("accept"); |
close(server_fd); |
server_fd = 0; |
serverPort = 0; |
serverIP = 0; |
} |
return; |
} |
|
if(gdb_fd) |
{ |
close(fd); |
return; |
} |
|
if(fcntl(fd,F_GETFL,&flags) < 0) |
{ |
sprintf(sTemp,"Unable to get flags for gdb socket %d",fd); |
perror(sTemp); |
close(fd); |
return; |
} |
|
if(fcntl(fd,F_SETFL, flags | O_NONBLOCK) < 0) |
{ |
sprintf(sTemp,"Unable to set flags for gdb socket %d to value 0x%08x", |
fd,flags | O_NONBLOCK); |
perror(sTemp); |
close(fd); |
return; |
} |
|
if(setsockopt(fd,SOL_TCP,TCP_NODELAY,&on_off,sizeof(int)) < 0) |
{ |
sprintf(sTemp,"Unable to disable Nagel's algorithm for socket %d.\nsetsockopt",fd); |
perror(sTemp); |
close(fd); |
return; |
} |
|
gdb_fd = fd; |
} |
|
void GDBRequest() |
{ |
/* Debug interface simulation should go here. */ |
} |
/trunk/or1ksim/sim-config.c
31,8 → 31,8
unsigned long val; |
|
memset(&config, 0, sizeof(config)); |
config.dc.tagtype = VIRTUAL; |
config.ic.tagtype = VIRTUAL; |
config.dc.tagtype = NONE/*VIRTUAL*/; |
config.ic.tagtype = NONE/*VIRTUAL*/; |
config.bp.bpb_sim = 1; |
config.bp.btic_sim = 1; |
config.clkcycle_ns = 4; /* 4 for 4ns (250MHz) */ |
64,9 → 64,65
|
argv++; argc--; |
while (argc) { |
if (argc && (*argv[0] != '-')) |
return 0; |
|
if (argc && (*argv[0] != '-')) { |
config.filename = argv[0]; |
argc--; |
argv++; |
} else |
if (strncmp(*argv, "-loadmem",8) == 0) { /* (CZ) */ |
MemoryBlock** block = &config.memory; |
int address = 0; |
|
if(!--argc) |
return 1; |
|
if(argv[0][8] == '@') |
{ |
char *s; |
|
address = strtol(address,&s,0); |
if(*s) |
return 1; |
} |
else if(argv[0][8]) |
return 1; |
|
while(*block) |
block = &(*block)->next; |
*block = (MemoryBlock*)malloc(sizeof(MemoryBlock)); |
memset(*block,0,sizeof(MemoryBlock)); |
(*block)->address = address; |
(*block)->file = *(++argv); |
argv++; argc--; |
} else |
if (strcmp(*argv, "-initmem") == 0) { /* (CZ) */ |
char *pattern,*s; |
if(!--argc) |
return 1; |
pattern = *(++argv); |
if(!strcmp(pattern,"random")) |
config.random_mem = 1; |
else |
{ |
val = strtol(pattern,&s,0); |
if(*s) |
return 1; |
config.pattern_mem = val; |
} |
} else |
if (strcmp(*argv, "-nosrv") == 0) { /* (CZ) */ |
config.inhibit_server = 1; |
argv++; argc--; |
} else |
if (strcmp(*argv, "-srv") == 0) { /* (CZ) */ |
char *s; |
if(!--argc) |
return 1; |
config.server_port = strtol(*(++argv),&s,10); |
if(*s) |
return 1; |
argv++; argc--; |
} else |
if (strcmp(*argv, "-i") == 0) { |
config.iprompt = 1; |
argv++; argc--; |
/trunk/or1ksim/support/simprintf.c
40,16 → 40,17
unsigned long fmtaddr; |
FILE *f; |
int i; |
|
int breakpoint = 0; |
|
#if STACK_ARGS |
fmtaddr = eval_mem32(stackaddr); |
fmtaddr = eval_mem32(stackaddr,&breakpoint); |
#else |
fmtaddr = regparam; |
#endif |
|
i = 0; |
while (eval_mem8(fmtaddr) != '\0') { |
fmtstr[i++] = eval_mem8(fmtaddr); |
while (eval_mem8(fmtaddr,&breakpoint) != '\0') { |
fmtstr[i++] = eval_mem8(fmtaddr,&breakpoint); |
fmtaddr++; |
if (i == FMTLEN - 1) |
break; |
64,7 → 65,8
unsigned long fmtaddr; |
FILE *f; |
int i = 0; |
|
int breakpoint = 0; |
|
simgetstr(stackaddr, regparam); |
|
debug("simprintf: stackaddr: 0x%.8lx", stackaddr); |
90,7 → 92,7
debug(" 3"); |
#if STACK_ARGS |
argaddr += 4; |
arg = eval_mem32(argaddr); |
arg = eval_mem32(argaddr,&breakpoint); |
#else |
sprintf(regstr, "r%u", ++argaddr); |
arg = eval_reg(regstr); |
99,14 → 101,14
if (strncmp(fmtstrpart, "%s", 2) == 0) { |
int len = 0; |
char *str; |
for(; eval_mem8(arg++); len++); |
for(; eval_mem8(arg++,&breakpoint); len++); |
len++; /* for null char */ |
arg -= len; |
str = (char *)malloc(len); |
len = 0; |
for(; eval_mem8(arg); len++) |
*(str+len) = eval_mem8(arg++); |
*(str+len) = eval_mem8(arg); /* null ch */ |
for(; eval_mem8(arg,&breakpoint); len++) |
*(str+len) = eval_mem8(arg++,&breakpoint); |
*(str+len) = eval_mem8(arg,&breakpoint); /* null ch */ |
/* debug("4a: len=%d str=%s\n", len, str); |
debug("4b:"); */ |
fprintf(f, fmtstrpart, str); |
/trunk/or1ksim/support/dumpverilog.c
36,6 → 36,7
#include "stats.h" |
#include "except.h" |
#include "dumpverilog.h" |
#include "or32.h" |
|
extern struct mem_entry mem[MEMORY_LEN]; |
extern char rcsrev[]; |
45,12 → 46,13
unsigned int i, done = 0; |
struct label_entry *tmp; |
char dis[DISWIDTH + 100]; |
|
int breakpoint = 0; |
|
printf("// This file was generated by or1ksim %s\n", rcsrev); |
printf(OR1K_MEM_VERILOG_HEADER(verilog_modname, from/DWQ, to/DWQ, (DISWIDTH*8))); |
|
for(i = from; i < to && i < (MEMORY_START + MEMORY_LEN); i++) { |
if (mem[i].insn) { |
if (mem[i].insn->insn_index >= 0) { |
tmp = mem[i].label; |
for(; tmp; tmp = tmp->next) |
printf("\n//\t%s%s", tmp->name, LABELEND_CHAR); |
58,7 → 60,7
printf("\n\tmem['h%x] = %d'h%.2x%.2x", i/DWQ, DW, mem[i].data, mem[i+1].data); |
printf("%.2x%.2x;", mem[i+2].data, mem[i+3].data); |
if (mem[i].insn) |
sprintf(dis, "%s %s", mem[i].insn->insn, mem[i].insn->op1); |
sprintf(dis, "%s %s", insn_name(mem[i].insn->insn_index), mem[i].insn->op1); |
if (strlen(mem[i].insn->op2)) |
sprintf(dis, "%s%s%s", dis, OPERAND_DELIM, mem[i].insn->op2); |
if (strlen(mem[i].insn->op3)) |
70,7 → 72,7
dis[DISWIDTH] = '\0'; |
printf("\n\tdis['h%x] = {\"%s\"};", i/DWQ, dis); |
dis[0] = '\0'; |
i += (insn_len(mem[i].insn->insn) - 1); |
i += (insn_len(mem[i].insn->insn_index) - 1); |
} else |
{ |
if (i % 64 == 0) |
93,10 → 95,10
printf("\n%.8x: ", i); |
|
/* don't print ascii chars below 0x20. */ |
if (evalsim_mem32(i) < 0x20) |
printf("0x%.2x ", (unsigned char)evalsim_mem32(i)); |
if (evalsim_mem32(i,&breakpoint) < 0x20) |
printf("0x%.2x ", (unsigned char)evalsim_mem32(i,&breakpoint)); |
else |
printf("0x%.2x'%c' ", (unsigned char)evalsim_mem32(i), (unsigned char)evalsim_mem32(i)); |
printf("0x%.2x'%c' ", (unsigned char)evalsim_mem32(i,&breakpoint), (unsigned char)evalsim_mem32(i,&breakpoint)); |
|
} |
printf(OR1K_MEM_VERILOG_FOOTER); |
106,12 → 108,13
void dumphex(unsigned int from, unsigned int to) |
{ |
unsigned int i, done = 0; |
|
int breakpoint = 0; |
|
for(i = from; i < to && i < (MEMORY_START + MEMORY_LEN); i++) { |
if (mem[i].insn) { |
printf("%.2x%.2x", mem[i].data, mem[i+1].data); |
printf("%.2x%.2x\n", mem[i+2].data, mem[i+3].data); |
i += (insn_len(mem[i].insn->insn) - 1); |
i += (insn_len(mem[i].insn->insn_index) - 1); |
} else |
{ |
printf("%.2x\n", (unsigned char)mem[i].data); |
126,6 → 129,6
/* this needs to be fixed */ |
|
for(i = from; i < to; i++) { |
printf("%.2x", (unsigned char)evalsim_mem32(i)); |
printf("%.2x", (unsigned char)evalsim_mem32(i,&breakpoint)); |
} |
} |