OpenCores
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));
}
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.