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:
Jackie Smith Cashion 1996-05-08 14:22:12 +00:00
parent aefee5c89f
commit f7481d45a5
2 changed files with 163 additions and 12 deletions

View File

@ -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>
* interp.c (sim_do_command): Complain if callback structure not

View File

@ -61,6 +61,9 @@ code on the hardware.
#include "engine.c"
#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
trap is required. NOTE: Care must be taken, since this value may be
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 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 */
#define DELAYSLOT() {\
@ -447,6 +450,19 @@ ut_reg profile_maxpc;
int profile_shift = 0; /* address shift amount */
#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 ------------------------------------------------*/
/*---------------------------------------------------------------------------*/
@ -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 void SignalException PARAMS((int exception,...));
static void simulate PARAMS((void));
static long getnum(char *value);
extern void sim_size(unsigned int newsize);
extern void sim_set_profile(int frequency);
static unsigned int power2(unsigned int value);
static long getnum PARAMS((char *value));
extern void sim_size PARAMS((unsigned int newsize));
extern void sim_set_profile PARAMS((int frequency));
static unsigned int power2 PARAMS((unsigned int value));
/*---------------------------------------------------------------------------*/
void
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);
else {
if (register_widths[rn] == 32)
registers[rn] = *((unsigned int *)memory);
registers[rn] = host_read_word(memory);
else
registers[rn] = *((uword64 *)memory);
registers[rn] = host_read_long(memory);
}
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);
else {
if (register_widths[rn] == 32)
*((unsigned int *)memory) = (registers[rn] & 0xFFFFFFFF);
*((unsigned int *)memory) = host_swap_word(registers[rn] & 0xFFFFFFFF);
else /* 64bit register */
*((uword64 *)memory) = registers[rn];
*((uword64 *)memory) = host_swap_long(registers[rn]);
}
return;
}
@ -1721,6 +1739,95 @@ void dotrace(tracefh,type,address,width,comment)
}
#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 -------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
@ -1762,6 +1869,35 @@ ColdReset()
}
#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;
}
@ -3441,9 +3577,6 @@ simulate ()
callback->printf_filtered(callback,"DBG: fetched 0x%08X from PC = 0x%08X%08X\n",instruction,WORD64HI(PC),WORD64LO(PC));
#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)
instruction_fetches++;
/* Since we increment above, the value should only ever be zero if