mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-01 13:26:47 +08:00
* cp1.c (value_fpr): Don't inherit existing FPR_STATE for
uninterpreted formats. If fmt is one of the uninterpreted types don't update the FPR_STATE. Handle fmt_uninterpreted_32 like fmt_word, and fmt_uninterpreted_64 like fmt_long. (store_fpr): When writing an invalid odd register, set the matching even register to fmt_unknown, not the following register. * interp.c (sim_open): If STATE_MEM_SIZE isn't set then set it to the the memory window at offset 0 set by --memory-size command line option. (sim_store_register): Handle storing 4 bytes to an 8 byte floating point register. (sim_fetch_register): Likewise for reading 4 bytes from an 8 byte register. (sim_monitor): When returning the memory size to the MIPS application, use the value in STATE_MEM_SIZE, not an arbitrary hardcoded value. (cop_lw): Don' mess around with FPR_STATE, just pass fmt_uninterpreted_32 to StoreFPR. (cop_sw): Similarly. (cop_ld): Pass fmt_uninterpreted_64 not fmt_uninterpreted. (cop_sd): Similarly. * mips.igen (not_word_value): Single version for mips32, mips64 and mips16.
This commit is contained in:
parent
b8e558488c
commit
14fb6c5a50
@ -1,3 +1,31 @@
|
||||
2007-02-19 Thiemo Seufer <ths@mips.com>
|
||||
Nigel Stephens <nigel@mips.com>
|
||||
David Ung <davidu@mips.com>
|
||||
|
||||
* cp1.c (value_fpr): Don't inherit existing FPR_STATE for
|
||||
uninterpreted formats. If fmt is one of the uninterpreted types
|
||||
don't update the FPR_STATE. Handle fmt_uninterpreted_32 like
|
||||
fmt_word, and fmt_uninterpreted_64 like fmt_long.
|
||||
(store_fpr): When writing an invalid odd register, set the
|
||||
matching even register to fmt_unknown, not the following register.
|
||||
* interp.c (sim_open): If STATE_MEM_SIZE isn't set then set it to
|
||||
the the memory window at offset 0 set by --memory-size command
|
||||
line option.
|
||||
(sim_store_register): Handle storing 4 bytes to an 8 byte floating
|
||||
point register.
|
||||
(sim_fetch_register): Likewise for reading 4 bytes from an 8 byte
|
||||
register.
|
||||
(sim_monitor): When returning the memory size to the MIPS
|
||||
application, use the value in STATE_MEM_SIZE, not an arbitrary
|
||||
hardcoded value.
|
||||
(cop_lw): Don' mess around with FPR_STATE, just pass
|
||||
fmt_uninterpreted_32 to StoreFPR.
|
||||
(cop_sw): Similarly.
|
||||
(cop_ld): Pass fmt_uninterpreted_64 not fmt_uninterpreted.
|
||||
(cop_sd): Similarly.
|
||||
* mips.igen (not_word_value): Single version for mips32, mips64
|
||||
and mips16.
|
||||
|
||||
2007-02-19 Thiemo Seufer <ths@mips.com>
|
||||
Nigel Stephens <nigel@mips.com>
|
||||
|
||||
|
@ -111,10 +111,10 @@ value_fpr (sim_cpu *cpu,
|
||||
int err = 0;
|
||||
|
||||
/* Treat unused register values, as fixed-point 64bit values. */
|
||||
if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
|
||||
if (fmt == fmt_unknown)
|
||||
{
|
||||
#if 1
|
||||
/* If request to read data as "uninterpreted", then use the current
|
||||
/* If request to read data as "unknown", then use the current
|
||||
encoding: */
|
||||
fmt = FPR_STATE[fpr];
|
||||
#else
|
||||
@ -123,20 +123,23 @@ value_fpr (sim_cpu *cpu,
|
||||
}
|
||||
|
||||
/* For values not yet accessed, set to the desired format. */
|
||||
if (FPR_STATE[fpr] == fmt_uninterpreted)
|
||||
if (fmt < fmt_uninterpreted)
|
||||
{
|
||||
FPR_STATE[fpr] = fmt;
|
||||
if (FPR_STATE[fpr] == fmt_uninterpreted)
|
||||
{
|
||||
FPR_STATE[fpr] = fmt;
|
||||
#ifdef DEBUG
|
||||
printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
|
||||
fpu_format_name (fmt));
|
||||
printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
|
||||
fpu_format_name (fmt));
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
if (fmt != FPR_STATE[fpr])
|
||||
{
|
||||
sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
|
||||
fpr, fpu_format_name (FPR_STATE[fpr]),
|
||||
fpu_format_name (fmt), pr_addr (cia));
|
||||
FPR_STATE[fpr] = fmt_unknown;
|
||||
}
|
||||
else if (fmt != FPR_STATE[fpr])
|
||||
{
|
||||
sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
|
||||
fpr, fpu_format_name (FPR_STATE[fpr]),
|
||||
fpu_format_name (fmt), pr_addr (cia));
|
||||
FPR_STATE[fpr] = fmt_unknown;
|
||||
}
|
||||
}
|
||||
|
||||
if (FPR_STATE[fpr] == fmt_unknown)
|
||||
@ -156,11 +159,13 @@ value_fpr (sim_cpu *cpu,
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case fmt_uninterpreted_32:
|
||||
case fmt_single:
|
||||
case fmt_word:
|
||||
value = (FGR[fpr] & 0xFFFFFFFF);
|
||||
break;
|
||||
|
||||
case fmt_uninterpreted_64:
|
||||
case fmt_uninterpreted:
|
||||
case fmt_double:
|
||||
case fmt_long:
|
||||
@ -177,11 +182,13 @@ value_fpr (sim_cpu *cpu,
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case fmt_uninterpreted_32:
|
||||
case fmt_single:
|
||||
case fmt_word:
|
||||
value = (FGR[fpr] & 0xFFFFFFFF);
|
||||
break;
|
||||
|
||||
case fmt_uninterpreted_64:
|
||||
case fmt_uninterpreted:
|
||||
case fmt_double:
|
||||
case fmt_long:
|
||||
@ -299,7 +306,7 @@ store_fpr (sim_cpu *cpu,
|
||||
else
|
||||
{
|
||||
FPR_STATE[fpr] = fmt_unknown;
|
||||
FPR_STATE[fpr + 1] = fmt_unknown;
|
||||
FPR_STATE[fpr ^ 1] = fmt_unknown;
|
||||
SignalException (ReservedInstruction, 0);
|
||||
}
|
||||
break;
|
||||
|
@ -131,6 +131,9 @@ static void ColdReset PARAMS((SIM_DESC sd));
|
||||
|
||||
/* Note that the monitor code essentially assumes this layout of memory.
|
||||
If you change these, change the monitor code, too. */
|
||||
/* FIXME Currently addresses are truncated to 32-bits, see
|
||||
mips/sim-main.c:address_translation(). If that changes, then these
|
||||
values will need to be extended, and tested for more carefully. */
|
||||
#define K0BASE (0x80000000)
|
||||
#define K0SIZE (0x20000000)
|
||||
#define K1BASE (0xA0000000)
|
||||
@ -365,17 +368,67 @@ sim_open (kind, cb, abfd, argv)
|
||||
if (board == NULL)
|
||||
{
|
||||
/* Allocate core managed memory */
|
||||
|
||||
sim_memopt *entry, *match = NULL;
|
||||
address_word mem_size = 0;
|
||||
int mapped = 0;
|
||||
|
||||
/* For compatibility with the old code - under this (at level one)
|
||||
are the kernel spaces K0 & K1. Both of these map to a single
|
||||
smaller sub region */
|
||||
sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
|
||||
sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
|
||||
K1BASE, K0SIZE,
|
||||
MEM_SIZE, /* actual size */
|
||||
K0BASE);
|
||||
|
||||
|
||||
/* Look for largest memory region defined on command-line at
|
||||
phys address 0. */
|
||||
#ifdef SIM_HAVE_FLATMEM
|
||||
mem_size = STATE_MEM_SIZE (sd);
|
||||
#endif
|
||||
for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
|
||||
{
|
||||
/* If we find an entry at address 0, then we will end up
|
||||
allocating a new buffer in the "memory alias" command
|
||||
below. The region at address 0 will be deleted. */
|
||||
address_word size = (entry->modulo != 0
|
||||
? entry->modulo : entry->nr_bytes);
|
||||
if (entry->addr == 0
|
||||
&& (!match || entry->level < match->level))
|
||||
match = entry;
|
||||
else if (entry->addr == K0BASE || entry->addr == K1BASE)
|
||||
mapped = 1;
|
||||
else
|
||||
{
|
||||
sim_memopt *alias;
|
||||
for (alias = entry->alias; alias != NULL; alias = alias->next)
|
||||
{
|
||||
if (alias->addr == 0
|
||||
&& (!match || entry->level < match->level))
|
||||
match = entry;
|
||||
else if (alias->addr == K0BASE || alias->addr == K1BASE)
|
||||
mapped = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mapped)
|
||||
{
|
||||
if (match)
|
||||
{
|
||||
/* Get existing memory region size. */
|
||||
mem_size = (match->modulo != 0
|
||||
? match->modulo : match->nr_bytes);
|
||||
/* Delete old region. */
|
||||
sim_do_commandf (sd, "memory delete %d:0x%lx@%d",
|
||||
match->space, match->addr, match->level);
|
||||
}
|
||||
else if (mem_size == 0)
|
||||
mem_size = MEM_SIZE;
|
||||
/* Limit to KSEG1 size (512MB) */
|
||||
if (mem_size > K1SIZE)
|
||||
mem_size = K1SIZE;
|
||||
/* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
|
||||
sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
|
||||
K1BASE, K1SIZE, (long)mem_size, K0BASE);
|
||||
}
|
||||
|
||||
device_init(sd);
|
||||
}
|
||||
else if (board != NULL
|
||||
@ -868,8 +921,16 @@ sim_store_register (sd,rn,memory,length)
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory);
|
||||
return 8;
|
||||
if (length == 8)
|
||||
{
|
||||
cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory);
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -889,8 +950,16 @@ sim_store_register (sd,rn,memory,length)
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
|
||||
return 8;
|
||||
if (length == 8)
|
||||
{
|
||||
cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->registers[rn] = (signed32) T2H_4(*(unsigned32*)memory);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -939,8 +1008,16 @@ sim_fetch_register (sd,rn,memory,length)
|
||||
}
|
||||
else
|
||||
{
|
||||
*(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]);
|
||||
return 8;
|
||||
if (length == 8)
|
||||
{
|
||||
*(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]);
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->fgr[rn - FGR_BASE]));
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -960,8 +1037,17 @@ sim_fetch_register (sd,rn,memory,length)
|
||||
}
|
||||
else
|
||||
{
|
||||
*(unsigned64*)memory = H2T_8 ((unsigned64)(cpu->registers[rn]));
|
||||
return 8;
|
||||
if (length == 8)
|
||||
{
|
||||
*(unsigned64*)memory =
|
||||
H2T_8 ((unsigned64) (cpu->registers[rn]));
|
||||
return 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1235,8 +1321,39 @@ sim_monitor (SIM_DESC sd,
|
||||
/* [A0 + 4] = instruction cache size */
|
||||
/* [A0 + 8] = data cache size */
|
||||
{
|
||||
unsigned_4 value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */;
|
||||
unsigned_4 value;
|
||||
unsigned_4 zero = 0;
|
||||
address_word mem_size;
|
||||
sim_memopt *entry, *match = NULL;
|
||||
|
||||
/* Search for memory region mapped to KSEG0 or KSEG1. */
|
||||
for (entry = STATE_MEMOPT (sd);
|
||||
entry != NULL;
|
||||
entry = entry->next)
|
||||
{
|
||||
if ((entry->addr == K0BASE || entry->addr == K1BASE)
|
||||
&& (!match || entry->level < match->level))
|
||||
match = entry;
|
||||
else
|
||||
{
|
||||
sim_memopt *alias;
|
||||
for (alias = entry->alias;
|
||||
alias != NULL;
|
||||
alias = alias->next)
|
||||
if ((alias->addr == K0BASE || alias->addr == K1BASE)
|
||||
&& (!match || entry->level < match->level))
|
||||
match = entry;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get region size, limit to KSEG1 size (512MB). */
|
||||
SIM_ASSERT (match != NULL);
|
||||
mem_size = (match->modulo != 0
|
||||
? match->modulo : match->nr_bytes);
|
||||
if (mem_size > K1SIZE)
|
||||
mem_size = K1SIZE;
|
||||
|
||||
value = mem_size;
|
||||
H2T (value);
|
||||
sim_write (sd, A0 + 0, (char *)&value, 4);
|
||||
sim_write (sd, A0 + 4, (char *)&zero, 4);
|
||||
@ -1924,8 +2041,7 @@ cop_lw (SIM_DESC sd,
|
||||
#ifdef DEBUG
|
||||
printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
|
||||
#endif
|
||||
StoreFPR(coproc_reg,fmt_word,(uword64)memword);
|
||||
FPR_STATE[coproc_reg] = fmt_uninterpreted;
|
||||
StoreFPR(coproc_reg,fmt_uninterpreted_32,(uword64)memword);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1956,7 +2072,7 @@ cop_ld (SIM_DESC sd,
|
||||
case 1:
|
||||
if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
|
||||
{
|
||||
StoreFPR(coproc_reg,fmt_uninterpreted,memword);
|
||||
StoreFPR(coproc_reg,fmt_uninterpreted_64,memword);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1987,11 +2103,7 @@ cop_sw (SIM_DESC sd,
|
||||
case 1:
|
||||
if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
|
||||
{
|
||||
FP_formats hold;
|
||||
hold = FPR_STATE[coproc_reg];
|
||||
FPR_STATE[coproc_reg] = fmt_word;
|
||||
value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
|
||||
FPR_STATE[coproc_reg] = hold;
|
||||
value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted_32);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2018,7 +2130,7 @@ cop_sd (SIM_DESC sd,
|
||||
case 1:
|
||||
if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
|
||||
{
|
||||
value = ValueFPR(coproc_reg,fmt_uninterpreted);
|
||||
value = ValueFPR(coproc_reg,fmt_uninterpreted_64);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -176,29 +176,18 @@
|
||||
*vr4100:
|
||||
*vr5000:
|
||||
*r3900:
|
||||
{
|
||||
/* For historical simulator compatibility (until documentation is
|
||||
found that makes these operations unpredictable on some of these
|
||||
architectures), this check never returns true. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
:function:::int:not_word_value:unsigned_word value
|
||||
*mips32:
|
||||
*mips32r2:
|
||||
{
|
||||
/* On MIPS32, since registers are 32-bits, there's no check to be done. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
:function:::int:not_word_value:unsigned_word value
|
||||
*mips64:
|
||||
*mips64r2:
|
||||
{
|
||||
return ((value >> 32) != (value & 0x80000000 ? 0xFFFFFFFF : 0));
|
||||
#if WITH_TARGET_WORD_BITSIZE == 64
|
||||
return value != (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Helper:
|
||||
//
|
||||
// Handle UNPREDICTABLE operation behaviour. The goal here is to prevent
|
||||
|
Loading…
Reference in New Issue
Block a user