mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-29 16:38:05 +08:00
* gencode.c (build_mips16_operands): Fix base PC value for PC
relative operands. (build_instruction): Call JALDELAYSLOT rather than DELAYSLOT for a jal instruction. * interp.c (simJALDELAYSLOT): Define. (JALDELAYSLOT): Define. (INDELAYSLOT, INJALDELAYSLOT): Define. (simulate): Clear simJALDELAYSLOT when simDELAYSLOT is cleared.
This commit is contained in:
@ -1,3 +1,33 @@
|
||||
Mon Dec 16 14:59:38 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* gencode.c (build_mips16_operands): Fix base PC value for PC
|
||||
relative operands.
|
||||
(build_instruction): Call JALDELAYSLOT rather than DELAYSLOT for a
|
||||
jal instruction.
|
||||
* interp.c (simJALDELAYSLOT): Define.
|
||||
(JALDELAYSLOT): Define.
|
||||
(INDELAYSLOT, INJALDELAYSLOT): Define.
|
||||
(simulate): Clear simJALDELAYSLOT when simDELAYSLOT is cleared.
|
||||
|
||||
Wed Dec 11 13:53:51 1996 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
* gencode.c (build_instruction): Use !ByteSwapMem instead of
|
||||
BigEndianMem.
|
||||
* interp.c (CONFIG, config_EP_{mask,shift,D,DxxDxx, config_BE): Delete.
|
||||
(BigEndianMem): Rename to ByteSwapMem and change sense.
|
||||
(BigEndianCPU, sim_write, LoadMemory, StoreMemory): Change
|
||||
BigEndianMem references to !ByteSwapMem.
|
||||
(set_endianness): New function, with prototype.
|
||||
(sim_open): Call set_endianness.
|
||||
(sim_info): Use simBE instead of BigEndianMem.
|
||||
(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): Delete unnecessary MSC_VER
|
||||
ifdefs, keeping the prototype declaration.
|
||||
(swap_word): Rewrite correctly.
|
||||
(ColdReset): Delete references to CONFIG. Delete endianness related
|
||||
code; moved to set_endianness.
|
||||
|
||||
Tue Dec 10 11:32:04 1996 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
* gencode.c (build_instruction, case JUMP): Truncate PC to 32 bits.
|
||||
|
@ -954,10 +954,10 @@ build_mips16_operands (bitmap)
|
||||
{
|
||||
int j;
|
||||
|
||||
printf ("PC & ~ (uword64) 1");
|
||||
printf ("((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : IPC) & ~ (uword64) 1)");
|
||||
for (j = 0; j < opindex; j++)
|
||||
if (ops[j]->shift != 0)
|
||||
printf (" & 0x%x", ~ ((1 << op->shift) - 1));
|
||||
printf (" & ~ (uword64) 0x%x", (1 << ops[j]->shift) - 1);
|
||||
}
|
||||
else if ((op->flags & MIPS16_ZERO) != 0)
|
||||
printf ("0");
|
||||
@ -1867,7 +1867,10 @@ build_instruction (doisa, features, mips16, insn)
|
||||
printf(" op1 = WORD64LO(op1);\n");
|
||||
printf(" /* NOTE: The jump occurs AFTER the next instruction has been executed */\n");
|
||||
printf(" DSPC = op1;\n");
|
||||
printf(" DELAYSLOT();\n");
|
||||
if (insn->flags & LINK)
|
||||
printf(" JALDELAYSLOT();\n");
|
||||
else
|
||||
printf(" DELAYSLOT();\n");
|
||||
break ;
|
||||
|
||||
case BRANCH: /* execute delay slot instruction before branch unless (LIKELY && branch_not_taken) */
|
||||
|
@ -231,9 +231,6 @@ static ut_reg EPC = 0; /* Exception PC */
|
||||
static FP_formats fpr_state[32];
|
||||
#endif /* HASFPU */
|
||||
|
||||
/* VR4300 CP0 configuration register: */
|
||||
static unsigned int CONFIG = 0;
|
||||
|
||||
/* The following are internal simulator state variables: */
|
||||
static ut_reg IPC = 0; /* internal Instruction PC */
|
||||
static ut_reg DSPC = 0; /* delay-slot PC */
|
||||
@ -257,13 +254,6 @@ static ut_reg DSPC = 0; /* delay-slot PC */
|
||||
#define status_ERL (1 << 2) /* Error level */
|
||||
#define status_RP (1 << 27) /* Reduced Power mode */
|
||||
|
||||
#define config_EP_mask (0xF)
|
||||
#define config_EP_shift (27)
|
||||
#define config_EP_D (0x0)
|
||||
#define config_EP_DxxDxx (0x6)
|
||||
|
||||
#define config_BE (1 << 15)
|
||||
|
||||
#define cause_BD ((unsigned)1 << 31) /* Exception in branch delay slot */
|
||||
|
||||
#if defined(HASFPU)
|
||||
@ -331,6 +321,7 @@ static ut_reg pending_slot_value[PSLOTS];
|
||||
static void dotrace PARAMS((FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...));
|
||||
static void sim_warning PARAMS((char *fmt,...));
|
||||
extern void sim_error PARAMS((char *fmt,...));
|
||||
static void set_endianness PARAMS((void));
|
||||
static void ColdReset PARAMS((void));
|
||||
static int AddressTranslation PARAMS((uword64 vAddr,int IorD,int LorS,uword64 *pAddr,int *CCA,int host,int raw));
|
||||
static void StoreMemory PARAMS((int CCA,int AccessLength,uword64 MemElem,uword64 pAddr,uword64 vAddr,int raw));
|
||||
@ -399,14 +390,9 @@ static ut_reg HLPC = 0;
|
||||
/* UserMode */
|
||||
#define UserMode ((((SR & status_KSU_mask) >> status_KSU_shift) == ksu_user) ? 1 : 0)
|
||||
|
||||
/* BigEndianMem */
|
||||
/* Hardware configuration. Affects endianness of LoadMemory and
|
||||
StoreMemory and the endianness of Kernel and Supervisor mode
|
||||
execution. The value is 0 for little-endian; 1 for big-endian. */
|
||||
#define BigEndianMem ((CONFIG & config_BE) ? 1 : 0)
|
||||
/* NOTE: Problems will occur if the simulator memory model does not
|
||||
match the host program expectation. i.e. if the host is writing
|
||||
big-endian values to a little-endian memory model. */
|
||||
/* ByteSwapMem */
|
||||
/* This is true if the host and target have different endianness. */
|
||||
#define ByteSwapMem (!(state & simHOSTBE) != !(state & simBE))
|
||||
|
||||
/* ReverseEndian */
|
||||
/* This mode is selected if in User mode with the RE bit being set in
|
||||
@ -418,8 +404,8 @@ static ut_reg HLPC = 0;
|
||||
/* The endianness for load and store instructions (0=little;1=big). In
|
||||
User mode this endianness may be switched by setting the state_RE
|
||||
bit in the SR register. Thus, BigEndianCPU may be computed as
|
||||
(BigEndienMem EOR ReverseEndian). */
|
||||
#define BigEndianCPU (BigEndianMem ^ ReverseEndian) /* Already bits */
|
||||
(!ByteSwapMem EOR ReverseEndian). */
|
||||
#define BigEndianCPU (!ByteSwapMem ^ ReverseEndian) /* Already bits */
|
||||
|
||||
#if !defined(FASTSIM) || defined(PROFILE)
|
||||
/* At the moment these values will be the same, since we do not have
|
||||
@ -449,6 +435,7 @@ static 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 */
|
||||
#define simSIGINT (1 << 28) /* 0 = do nothing; 1 = SIGINT has occured */
|
||||
#define simJALDELAYSLOT (1 << 29) /* 1 = in jal delay slot */
|
||||
|
||||
static unsigned int state = 0;
|
||||
static unsigned int rcexit = 0; /* _exit() reason code holder */
|
||||
@ -459,11 +446,19 @@ static unsigned int rcexit = 0; /* _exit() reason code holder */
|
||||
state |= simDELAYSLOT;\
|
||||
}
|
||||
|
||||
#define JALDELAYSLOT() {\
|
||||
DELAYSLOT ();\
|
||||
state |= simJALDELAYSLOT;\
|
||||
}
|
||||
|
||||
#define NULLIFY() {\
|
||||
state &= ~simDELAYSLOT;\
|
||||
state |= simSKIPNEXT;\
|
||||
}
|
||||
|
||||
#define INDELAYSLOT() ((state & simDELAYSLOT) != 0)
|
||||
#define INJALDELAYSLOT() ((state & simJALDELAYSLOT) != 0)
|
||||
|
||||
#define K0BASE (0x80000000)
|
||||
#define K0SIZE (0x20000000)
|
||||
#define K1BASE (0xA0000000)
|
||||
@ -544,6 +539,8 @@ sim_open (args)
|
||||
state |= simHOSTBE; /* big-endian host */
|
||||
}
|
||||
|
||||
set_endianness ();
|
||||
|
||||
#if defined(HASFPU)
|
||||
/* Check that the host FPU conforms to IEEE 754-1985 for the SINGLE
|
||||
and DOUBLE binary formats. This is a bit nasty, requiring that we
|
||||
@ -1057,7 +1054,7 @@ sim_write (addr,buffer,size)
|
||||
/* We need to perform the following magic to ensure that that
|
||||
bytes are written into same byte positions in the target memory
|
||||
world, regardless of the endianness of the host. */
|
||||
if (BigEndianMem) {
|
||||
if (!ByteSwapMem) {
|
||||
value = ((uword64)(*buffer++) << 8);
|
||||
value |= ((uword64)(*buffer++) << 0);
|
||||
} else {
|
||||
@ -1074,7 +1071,7 @@ sim_write (addr,buffer,size)
|
||||
int cca;
|
||||
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
|
||||
uword64 value;
|
||||
if (BigEndianMem) {
|
||||
if (!ByteSwapMem) {
|
||||
value = ((uword64)(*buffer++) << 24);
|
||||
value |= ((uword64)(*buffer++) << 16);
|
||||
value |= ((uword64)(*buffer++) << 8);
|
||||
@ -1095,7 +1092,7 @@ sim_write (addr,buffer,size)
|
||||
int cca;
|
||||
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
|
||||
uword64 value;
|
||||
if (BigEndianMem) {
|
||||
if (!ByteSwapMem) {
|
||||
value = ((uword64)(*buffer++) << 56);
|
||||
value |= ((uword64)(*buffer++) << 48);
|
||||
value |= ((uword64)(*buffer++) << 40);
|
||||
@ -1278,7 +1275,7 @@ sim_info (verbose)
|
||||
|
||||
callback->printf_filtered(callback,"MIPS %d-bit simulator\n",(PROCESSOR_64BIT ? 64 : 32));
|
||||
|
||||
callback->printf_filtered(callback,"%s endian memory model\n",(BigEndianMem ? "Big" : "Little"));
|
||||
callback->printf_filtered(callback,"%s endian memory model\n",(state & simBE ? "Big" : "Little"));
|
||||
|
||||
callback->printf_filtered(callback,"0x%08X bytes of memory at 0x%08X%08X\n",(unsigned int)membank_size,WORD64HI(membank_base),WORD64LO(membank_base));
|
||||
|
||||
@ -1962,67 +1959,37 @@ void dotrace(FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...
|
||||
simulation, at the cost of increasing the image and source size. */
|
||||
|
||||
static unsigned int
|
||||
#ifdef _MSC_VER
|
||||
xfer_direct_word(unsigned char *memory)
|
||||
#else
|
||||
xfer_direct_word(memory)
|
||||
unsigned char *memory;
|
||||
#endif
|
||||
{
|
||||
return *((unsigned int *)memory);
|
||||
}
|
||||
|
||||
static uword64
|
||||
#ifdef _MSC_VER
|
||||
xfer_direct_long(unsigned char *memory)
|
||||
#else
|
||||
xfer_direct_long(memory)
|
||||
unsigned char *memory;
|
||||
#endif
|
||||
{
|
||||
return *((uword64 *)memory);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
#ifdef _MSC_VER
|
||||
swap_direct_word(unsigned int data)
|
||||
#else
|
||||
swap_direct_word(data)
|
||||
unsigned int data;
|
||||
#endif
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
static uword64
|
||||
#ifdef _MSC_VER
|
||||
swap_direct_long(uword64 data)
|
||||
#else
|
||||
swap_direct_long(data)
|
||||
uword64 data;
|
||||
#endif
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
#ifdef _MSC_VER
|
||||
xfer_big_word(unsigned char *memory)
|
||||
#else
|
||||
xfer_big_word(memory)
|
||||
unsigned char *memory;
|
||||
#endif
|
||||
{
|
||||
return ((memory[0] << 24) | (memory[1] << 16) | (memory[2] << 8) | memory[3]);
|
||||
}
|
||||
|
||||
static uword64
|
||||
#ifdef _MSC_VER
|
||||
xfer_big_long(unsigned char *memory)
|
||||
#else
|
||||
xfer_big_long(memory)
|
||||
unsigned char *memory;
|
||||
#endif
|
||||
{
|
||||
return (((uword64)memory[0] << 56) | ((uword64)memory[1] << 48)
|
||||
| ((uword64)memory[2] << 40) | ((uword64)memory[3] << 32)
|
||||
@ -2031,23 +1998,13 @@ xfer_big_long(memory)
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
#ifdef _MSC_VER
|
||||
xfer_little_word(unsigned char *memory)
|
||||
#else
|
||||
xfer_little_word(memory)
|
||||
unsigned char *memory;
|
||||
#endif
|
||||
{
|
||||
return ((memory[3] << 24) | (memory[2] << 16) | (memory[1] << 8) | memory[0]);
|
||||
}
|
||||
|
||||
static uword64
|
||||
#ifdef _MSC_VER
|
||||
xfer_little_long(unsigned char *memory)
|
||||
#else
|
||||
xfer_little_long(memory)
|
||||
unsigned char *memory;
|
||||
#endif
|
||||
{
|
||||
return (((uword64)memory[7] << 56) | ((uword64)memory[6] << 48)
|
||||
| ((uword64)memory[5] << 40) | ((uword64)memory[4] << 32)
|
||||
@ -2056,27 +2013,16 @@ xfer_little_long(memory)
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
#ifdef _MSC_VER
|
||||
swap_word(unsigned int data)
|
||||
#else
|
||||
swap_word(data)
|
||||
unsigned int data;
|
||||
#endif
|
||||
{
|
||||
unsigned int result;
|
||||
result = data ^ ((data << 16) | (data >> 16));
|
||||
result &= ~0x00FF0000;
|
||||
data = (data << 24) | (data >> 8);
|
||||
return data ^ (result >> 8);
|
||||
result = (((data & 0xff) << 24) | ((data & 0xff00) << 8)
|
||||
| ((data >> 8) & 0xff00) | ((data >> 24) & 0xff));
|
||||
return result;
|
||||
}
|
||||
|
||||
static uword64
|
||||
#ifdef _MSC_VER
|
||||
swap_long(uword64 data)
|
||||
#else
|
||||
swap_long(data)
|
||||
uword64 data;
|
||||
#endif
|
||||
{
|
||||
unsigned int tmphi = WORD64HI(data);
|
||||
unsigned int tmplo = WORD64LO(data);
|
||||
@ -2090,6 +2036,36 @@ swap_long(data)
|
||||
/*-- simulator engine -------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
set_endianness ()
|
||||
{
|
||||
/* 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. */
|
||||
if (target_byte_order == 4321)
|
||||
state |= simBE;
|
||||
|
||||
/* ??? This is a lot more code than is necessary to solve the problem.
|
||||
It would be simpler to handle this like the SH simulator. */
|
||||
if (!ByteSwapMem) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ColdReset()
|
||||
{
|
||||
@ -2099,10 +2075,6 @@ ColdReset()
|
||||
|
||||
SR &= ~(status_SR | status_TS | status_RP);
|
||||
SR |= (status_ERL | status_BEV);
|
||||
/* VR4300 starts in Big-Endian mode */
|
||||
CONFIG &= ~(config_EP_mask << config_EP_shift);
|
||||
CONFIG |= ((config_EP_D << config_EP_shift) | config_BE);
|
||||
/* TODO: The VR4300 CONFIG register is not modelled fully at the moment */
|
||||
|
||||
#if defined(HASFPU) && (GPRLEN == (64))
|
||||
/* Cheat and allow access to the complete register set immediately: */
|
||||
@ -2127,35 +2099,6 @@ 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;
|
||||
}
|
||||
|
||||
@ -2353,7 +2296,7 @@ LoadMemory(CCA,AccessLength,pAddr,vAddr,IorD,raw)
|
||||
extracts the required bytes. However, to keep performance
|
||||
high we only load the required bytes into the relevant
|
||||
slots. */
|
||||
if (BigEndianMem)
|
||||
if (!ByteSwapMem)
|
||||
switch (AccessLength) { /* big-endian memory */
|
||||
case AccessLength_DOUBLEWORD :
|
||||
value |= ((uword64)mem[index++] << 56);
|
||||
@ -2405,7 +2348,7 @@ LoadMemory(CCA,AccessLength,pAddr,vAddr,IorD,raw)
|
||||
StoreMemory routines to avoid shifting the data before
|
||||
returning or using it. */
|
||||
if (!raw) { /* do nothing for raw accessess */
|
||||
if (BigEndianMem)
|
||||
if (!ByteSwapMem)
|
||||
value <<= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8);
|
||||
else /* little-endian only needs to be shifted up to the correct byte offset */
|
||||
value <<= ((pAddr & LOADDRMASK) * 8);
|
||||
@ -2483,7 +2426,7 @@ StoreMemory(CCA,AccessLength,MemElem,pAddr,vAddr,raw)
|
||||
printf("DBG: StoreMemory: offset = %d MemElem = 0x%08X%08X\n",(unsigned int)(pAddr & LOADDRMASK),WORD64HI(MemElem),WORD64LO(MemElem));
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (BigEndianMem) {
|
||||
if (!ByteSwapMem) {
|
||||
if (raw)
|
||||
shift = ((7 - AccessLength) * 8);
|
||||
else /* real memory access */
|
||||
@ -2499,7 +2442,7 @@ StoreMemory(CCA,AccessLength,MemElem,pAddr,vAddr,raw)
|
||||
printf("DBG: StoreMemory: shift = %d MemElem = 0x%08X%08X\n",shift,WORD64HI(MemElem),WORD64LO(MemElem));
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (BigEndianMem) {
|
||||
if (!ByteSwapMem) {
|
||||
switch (AccessLength) { /* big-endian memory */
|
||||
case AccessLength_DOUBLEWORD :
|
||||
mem[index++] = (unsigned char)(MemElem >> 56);
|
||||
@ -4040,7 +3983,7 @@ simulate ()
|
||||
printf("DBG: dsstate set before instruction execution - updating PC to 0x%08X%08X\n",WORD64HI(DSPC),WORD64LO(DSPC));
|
||||
#endif /* DEBUG */
|
||||
PC = DSPC;
|
||||
state &= ~simDELAYSLOT;
|
||||
state &= ~(simDELAYSLOT | simJALDELAYSLOT);
|
||||
}
|
||||
|
||||
if (MIPSISA < 4) { /* The following is only required on pre MIPS IV processors: */
|
||||
|
Reference in New Issue
Block a user