Wed May 8 15:12:58 1996 James G. Smith <jsmith@cygnus.co.uk>
* interp.c (xfer_direct_word, xfer_direct_long, swap_direct_word, swap_direct_long, xfer_big_word, xfer_big_long, xfer_little_word, xfer_little_long, swap_word,swap_long): Added. * interp.c (ColdReset): Provide function indirection to host<->simulated_target transfer routines. * interp.c (sim_store_register, sim_fetch_register): Updated to make use of indirected transfer routines.
This commit is contained in:
parent
aefee5c89f
commit
f7481d45a5
2 changed files with 163 additions and 12 deletions
|
@ -1,3 +1,21 @@
|
||||||
|
Wed May 8 15:12:58 1996 James G. Smith <jsmith@cygnus.co.uk>
|
||||||
|
|
||||||
|
* interp.c (xfer_direct_word, xfer_direct_long,
|
||||||
|
swap_direct_word, swap_direct_long, xfer_big_word,
|
||||||
|
xfer_big_long, xfer_little_word, xfer_little_long,
|
||||||
|
swap_word,swap_long): Added.
|
||||||
|
* interp.c (ColdReset): Provide function indirection to
|
||||||
|
host<->simulated_target transfer routines.
|
||||||
|
* interp.c (sim_store_register, sim_fetch_register): Updated to
|
||||||
|
make use of indirected transfer routines.
|
||||||
|
|
||||||
|
Fri Apr 19 15:48:24 1996 James G. Smith <jsmith@cygnus.co.uk>
|
||||||
|
|
||||||
|
* gencode.c (process_instructions): Ensure FP ABS instruction
|
||||||
|
recognised.
|
||||||
|
* interp.c (AbsoluteValue): Add routine. Also provide simple PMON
|
||||||
|
system call support.
|
||||||
|
|
||||||
Wed Apr 10 09:51:38 1996 James G. Smith <jsmith@cygnus.co.uk>
|
Wed Apr 10 09:51:38 1996 James G. Smith <jsmith@cygnus.co.uk>
|
||||||
|
|
||||||
* interp.c (sim_do_command): Complain if callback structure not
|
* interp.c (sim_do_command): Complain if callback structure not
|
||||||
|
|
|
@ -61,6 +61,9 @@ code on the hardware.
|
||||||
#include "engine.c"
|
#include "engine.c"
|
||||||
#undef SIM_MANIFESTS
|
#undef SIM_MANIFESTS
|
||||||
|
|
||||||
|
/* This variable holds the GDB view of the target endianness: */
|
||||||
|
extern int target_byte_order;
|
||||||
|
|
||||||
/* The following reserved instruction value is used when a simulator
|
/* The following reserved instruction value is used when a simulator
|
||||||
trap is required. NOTE: Care must be taken, since this value may be
|
trap is required. NOTE: Care must be taken, since this value may be
|
||||||
used in later revisions of the MIPS ISA. */
|
used in later revisions of the MIPS ISA. */
|
||||||
|
@ -405,7 +408,7 @@ unsigned int pipeline_ticks = 0;
|
||||||
#define simEXCEPTION (1 << 26) /* 0 = no exception; 1 = exception has occurred */
|
#define simEXCEPTION (1 << 26) /* 0 = no exception; 1 = exception has occurred */
|
||||||
#define simEXIT (1 << 27) /* 0 = do nothing; 1 = run-time exit() processing */
|
#define simEXIT (1 << 27) /* 0 = do nothing; 1 = run-time exit() processing */
|
||||||
|
|
||||||
unsigned int state = (0 | simBE); /* big-endian simulator by default */
|
unsigned int state = 0;
|
||||||
unsigned int rcexit = 0; /* _exit() reason code holder */
|
unsigned int rcexit = 0; /* _exit() reason code holder */
|
||||||
|
|
||||||
#define DELAYSLOT() {\
|
#define DELAYSLOT() {\
|
||||||
|
@ -447,6 +450,19 @@ ut_reg profile_maxpc;
|
||||||
int profile_shift = 0; /* address shift amount */
|
int profile_shift = 0; /* address shift amount */
|
||||||
#endif /* PROFILE */
|
#endif /* PROFILE */
|
||||||
|
|
||||||
|
/* The following are used to provide shortcuts to the required version
|
||||||
|
of host<->target copying. This avoids run-time conditionals, which
|
||||||
|
would slow the simulator throughput. */
|
||||||
|
typedef unsigned int (*fnptr_read_word) PARAMS((unsigned char *memory));
|
||||||
|
typedef unsigned int (*fnptr_swap_word) PARAMS((unsigned int data));
|
||||||
|
typedef uword64 (*fnptr_read_long) PARAMS((unsigned char *memory));
|
||||||
|
typedef uword64 (*fnptr_swap_long) PARAMS((uword64 data));
|
||||||
|
|
||||||
|
fnptr_read_word host_read_word;
|
||||||
|
fnptr_read_long host_read_long;
|
||||||
|
fnptr_swap_word host_swap_word;
|
||||||
|
fnptr_swap_long host_swap_long;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*-- GDB simulator interface ------------------------------------------------*/
|
/*-- GDB simulator interface ------------------------------------------------*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -459,10 +475,12 @@ static void StoreMemory PARAMS((int CCA,int AccessLength,uword64 MemElem,uword64
|
||||||
static uword64 LoadMemory PARAMS((int CCA,int AccessLength,uword64 pAddr,uword64 vAddr,int IorD,int raw));
|
static uword64 LoadMemory PARAMS((int CCA,int AccessLength,uword64 pAddr,uword64 vAddr,int IorD,int raw));
|
||||||
static void SignalException PARAMS((int exception,...));
|
static void SignalException PARAMS((int exception,...));
|
||||||
static void simulate PARAMS((void));
|
static void simulate PARAMS((void));
|
||||||
static long getnum(char *value);
|
static long getnum PARAMS((char *value));
|
||||||
extern void sim_size(unsigned int newsize);
|
extern void sim_size PARAMS((unsigned int newsize));
|
||||||
extern void sim_set_profile(int frequency);
|
extern void sim_set_profile PARAMS((int frequency));
|
||||||
static unsigned int power2(unsigned int value);
|
static unsigned int power2 PARAMS((unsigned int value));
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void
|
void
|
||||||
sim_open (args)
|
sim_open (args)
|
||||||
|
@ -1056,9 +1074,9 @@ sim_store_register (rn,memory)
|
||||||
callback->printf_filtered(callback,"Warning: Invalid register width for %d (register store ignored)\n",rn);
|
callback->printf_filtered(callback,"Warning: Invalid register width for %d (register store ignored)\n",rn);
|
||||||
else {
|
else {
|
||||||
if (register_widths[rn] == 32)
|
if (register_widths[rn] == 32)
|
||||||
registers[rn] = *((unsigned int *)memory);
|
registers[rn] = host_read_word(memory);
|
||||||
else
|
else
|
||||||
registers[rn] = *((uword64 *)memory);
|
registers[rn] = host_read_long(memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1077,9 +1095,9 @@ sim_fetch_register (rn,memory)
|
||||||
callback->printf_filtered(callback,"Warning: Invalid register width for %d (register fetch ignored)\n",rn);
|
callback->printf_filtered(callback,"Warning: Invalid register width for %d (register fetch ignored)\n",rn);
|
||||||
else {
|
else {
|
||||||
if (register_widths[rn] == 32)
|
if (register_widths[rn] == 32)
|
||||||
*((unsigned int *)memory) = (registers[rn] & 0xFFFFFFFF);
|
*((unsigned int *)memory) = host_swap_word(registers[rn] & 0xFFFFFFFF);
|
||||||
else /* 64bit register */
|
else /* 64bit register */
|
||||||
*((uword64 *)memory) = registers[rn];
|
*((uword64 *)memory) = host_swap_long(registers[rn]);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1721,6 +1739,95 @@ void dotrace(tracefh,type,address,width,comment)
|
||||||
}
|
}
|
||||||
#endif /* TRACE */
|
#endif /* TRACE */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*-- host<->target transfers ------------------------------------------------*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* The following routines allow conditionals to be avoided during the
|
||||||
|
simulation, at the cost of increasing the image and source size. */
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
xfer_direct_word(memory)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
return *((unsigned int *)memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uword64
|
||||||
|
xfer_direct_long(memory)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
return *((uword64 *)memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
swap_direct_word(data)
|
||||||
|
unsigned int data;
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uword64
|
||||||
|
swap_direct_long(data)
|
||||||
|
uword64 data;
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
xfer_big_word(memory)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
return ((memory[0] << 24) | (memory[1] << 16) | (memory[2] << 8) | memory[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uword64
|
||||||
|
xfer_big_long(memory)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
return (((uword64)memory[0] << 56) | ((uword64)memory[1] << 48)
|
||||||
|
| ((uword64)memory[2] << 40) | ((uword64)memory[3] << 32)
|
||||||
|
| (memory[4] << 24) | (memory[5] << 16) | (memory[6] << 8) | memory[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
xfer_little_word(memory)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
return ((memory[3] << 24) | (memory[2] << 16) | (memory[1] << 8) | memory[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uword64
|
||||||
|
xfer_little_long(memory)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
return (((uword64)memory[7] << 56) | ((uword64)memory[6] << 48)
|
||||||
|
| ((uword64)memory[5] << 40) | ((uword64)memory[4] << 32)
|
||||||
|
| (memory[3] << 24) | (memory[2] << 16) | (memory[1] << 8) | memory[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
swap_word(data)
|
||||||
|
unsigned int data;
|
||||||
|
{
|
||||||
|
unsigned int result;
|
||||||
|
result = data ^ ((data << 16) | (data >> 16));
|
||||||
|
result &= ~0x00FF0000;
|
||||||
|
data = (data << 24) | (data >> 8);
|
||||||
|
return data ^ (result >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uword64
|
||||||
|
swap_long(data)
|
||||||
|
uword64 data;
|
||||||
|
{
|
||||||
|
unsigned int tmphi = WORD64HI(data);
|
||||||
|
unsigned int tmplo = WORD64LO(data);
|
||||||
|
tmphi = swap_word(tmphi);
|
||||||
|
tmplo = swap_word(tmplo);
|
||||||
|
/* Now swap the HI and LO parts */
|
||||||
|
return SET64LO(tmphi) | SET64HI(tmplo);
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*-- simulator engine -------------------------------------------------------*/
|
/*-- simulator engine -------------------------------------------------------*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -1762,6 +1869,35 @@ ColdReset()
|
||||||
}
|
}
|
||||||
#endif /* HASFPU */
|
#endif /* HASFPU */
|
||||||
|
|
||||||
|
/* In reality this check should be performed at various points
|
||||||
|
within the simulation, since it is possible to change the
|
||||||
|
endianness of user programs. However, we perform the check here
|
||||||
|
to ensure that the start-of-day values agree: */
|
||||||
|
state |= (BigEndianCPU ? simBE : 0);
|
||||||
|
if ((target_byte_order == 1234) != !(state & simBE)) {
|
||||||
|
fprintf(stderr,"ColdReset: GDB (%s) and simulator (%s) do not agree on target endianness\n",
|
||||||
|
target_byte_order == 1234 ? "little" : "big",
|
||||||
|
state & simBE ? "big" : "little");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((state & simHOSTBE) == (state & simBE)) {
|
||||||
|
host_read_word = xfer_direct_word;
|
||||||
|
host_read_long = xfer_direct_long;
|
||||||
|
host_swap_word = swap_direct_word;
|
||||||
|
host_swap_long = swap_direct_long;
|
||||||
|
} else if (state & simHOSTBE) {
|
||||||
|
host_read_word = xfer_little_word;
|
||||||
|
host_read_long = xfer_little_long;
|
||||||
|
host_swap_word = swap_word;
|
||||||
|
host_swap_long = swap_long;
|
||||||
|
} else { /* HOST little-endian */
|
||||||
|
host_read_word = xfer_big_word;
|
||||||
|
host_read_long = xfer_big_long;
|
||||||
|
host_swap_word = swap_word;
|
||||||
|
host_swap_long = swap_long;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3441,9 +3577,6 @@ simulate ()
|
||||||
callback->printf_filtered(callback,"DBG: fetched 0x%08X from PC = 0x%08X%08X\n",instruction,WORD64HI(PC),WORD64LO(PC));
|
callback->printf_filtered(callback,"DBG: fetched 0x%08X from PC = 0x%08X%08X\n",instruction,WORD64HI(PC),WORD64LO(PC));
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*DBG*/ if (instruction == 0x46200005) /* ABS.D */
|
|
||||||
/*DBG*/ callback->printf_filtered(callback,"DBG: ABS.D (0x%08X) instruction\n",instruction);
|
|
||||||
|
|
||||||
#if !defined(FASTSIM) || defined(PROFILE)
|
#if !defined(FASTSIM) || defined(PROFILE)
|
||||||
instruction_fetches++;
|
instruction_fetches++;
|
||||||
/* Since we increment above, the value should only ever be zero if
|
/* Since we increment above, the value should only ever be zero if
|
||||||
|
|
Loading…
Add table
Reference in a new issue