2002-05-01 Chris Demetriou <cgd@broadcom.com>
* cp1.c (store_fpr): Remove #ifdef'd out call to UndefinedResult which wouldn't compile anyway. * sim-main.h (unpredictable_action): New function prototype. (Unpredictable): Define to call igen function unpredictable(). (NotWordValue): New macro to call igen function not_word_value(). (UndefinedResult): Remove. * interp.c (undefined_result): Remove. (unpredictable_action): New function. * mips.igen (not_word_value, unpredictable): New functions. (ADD, ADDI, do_addiu, do_addu, BGEZAL, BGEZALL, BLTZAL, BLTZALL) (CLO, CLZ, MADD, MADDU, MSUB, MSUBU, MUL, do_mult, do_multu) (do_sra, do_srav, do_srl, do_srlv, SUB, do_subu): Invoke NotWordValue() to check for unpredictable inputs, then Unpredictable() to handle them.
This commit is contained in:
parent
a6befae84d
commit
402586aa26
|
@ -1,3 +1,20 @@
|
|||
2002-05-01 Chris Demetriou <cgd@broadcom.com>
|
||||
|
||||
* cp1.c (store_fpr): Remove #ifdef'd out call to UndefinedResult
|
||||
which wouldn't compile anyway.
|
||||
* sim-main.h (unpredictable_action): New function prototype.
|
||||
(Unpredictable): Define to call igen function unpredictable().
|
||||
(NotWordValue): New macro to call igen function not_word_value().
|
||||
(UndefinedResult): Remove.
|
||||
* interp.c (undefined_result): Remove.
|
||||
(unpredictable_action): New function.
|
||||
* mips.igen (not_word_value, unpredictable): New functions.
|
||||
(ADD, ADDI, do_addiu, do_addu, BGEZAL, BGEZALL, BLTZAL, BLTZALL)
|
||||
(CLO, CLZ, MADD, MADDU, MSUB, MSUBU, MUL, do_mult, do_multu)
|
||||
(do_sra, do_srav, do_srl, do_srlv, SUB, do_subu): Invoke
|
||||
NotWordValue() to check for unpredictable inputs, then
|
||||
Unpredictable() to handle them.
|
||||
|
||||
2002-02-24 Chris Demetriou <cgd@broadcom.com>
|
||||
|
||||
* mips.igen: Fix formatting of calls to Unpredictable().
|
||||
|
|
|
@ -279,10 +279,6 @@ store_fpr (SIM_DESC sd,
|
|||
break;
|
||||
}
|
||||
}
|
||||
#if defined(WARN_RESULT)
|
||||
else
|
||||
UndefinedResult ();
|
||||
#endif /* WARN_RESULT */
|
||||
|
||||
if (err)
|
||||
SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
|
||||
|
|
|
@ -1869,28 +1869,31 @@ signal_exception (SIM_DESC sd,
|
|||
|
||||
|
||||
|
||||
#if defined(WARN_RESULT)
|
||||
/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
|
||||
/* This function indicates that the result of the operation is
|
||||
undefined. However, this should not affect the instruction
|
||||
stream. All that is meant to happen is that the destination
|
||||
register is set to an undefined result. To keep the simulator
|
||||
simple, we just don't bother updating the destination register, so
|
||||
the overall result will be undefined. If desired we can stop the
|
||||
simulator by raising a pseudo-exception. */
|
||||
#define UndefinedResult() undefined_result (sd,cia)
|
||||
static void
|
||||
undefined_result(sd,cia)
|
||||
SIM_DESC sd;
|
||||
address_word cia;
|
||||
/* This function implements what the MIPS32 and MIPS64 ISAs define as
|
||||
"UNPREDICTABLE" behaviour.
|
||||
|
||||
About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results
|
||||
may vary from processor implementation to processor implementation,
|
||||
instruction to instruction, or as a function of time on the same
|
||||
implementation or instruction. Software can never depend on results
|
||||
that are UNPREDICTABLE. ..." (MIPS64 Architecture for Programmers
|
||||
Volume II, The MIPS64 Instruction Set. MIPS Document MD00087 revision
|
||||
0.95, page 2.)
|
||||
|
||||
For UNPREDICTABLE behaviour, we print a message, if possible print
|
||||
the offending instructions mips.igen instruction name (provided by
|
||||
the caller), and stop the simulator.
|
||||
|
||||
XXX FIXME: eventually, stopping the simulator should be made conditional
|
||||
on a command-line option. */
|
||||
void
|
||||
unpredictable_action(sim_cpu *cpu, address_word cia)
|
||||
{
|
||||
sim_io_eprintf(sd,"UndefinedResult: PC = 0x%s\n",pr_addr(cia));
|
||||
#if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
|
||||
state |= simSTOP;
|
||||
#endif
|
||||
return;
|
||||
SIM_DESC sd = CPU_STATE(cpu);
|
||||
|
||||
sim_io_eprintf(sd, "UNPREDICTABLE: PC = 0x%s\n", pr_addr (cia));
|
||||
sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGABRT);
|
||||
}
|
||||
#endif /* WARN_RESULT */
|
||||
|
||||
|
||||
/*-- co-processor support routines ------------------------------------------*/
|
||||
|
|
|
@ -142,6 +142,70 @@
|
|||
}
|
||||
|
||||
|
||||
// Helper:
|
||||
//
|
||||
// Check that a 32-bit register value is properly sign-extended.
|
||||
// (See NotWordValue in ISA spec.)
|
||||
//
|
||||
|
||||
:function:::int:not_word_value:unsigned_word value
|
||||
*mipsI:
|
||||
*mipsII:
|
||||
*mipsIII:
|
||||
*mipsIV:
|
||||
*mipsV:
|
||||
*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:
|
||||
{
|
||||
/* 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:
|
||||
{
|
||||
return ((value >> 32) != (value & 0x80000000 ? 0xFFFFFFFF : 0));
|
||||
}
|
||||
|
||||
|
||||
// Helper:
|
||||
//
|
||||
// Handle UNPREDICTABLE operation behaviour. The goal here is to prevent
|
||||
// theoretically portable code which invokes non-portable behaviour from
|
||||
// running with no indication of the portability issue.
|
||||
// (See definition of UNPREDICTABLE in ISA spec.)
|
||||
//
|
||||
|
||||
:function:::void:unpredictable:
|
||||
*mipsI:
|
||||
*mipsII:
|
||||
*mipsIII:
|
||||
*mipsIV:
|
||||
*mipsV:
|
||||
*vr4100:
|
||||
*vr5000:
|
||||
*r3900:
|
||||
{
|
||||
}
|
||||
|
||||
:function:::void:unpredictable:
|
||||
*mips32:
|
||||
*mips64:
|
||||
{
|
||||
unpredictable_action (CPU, CIA);
|
||||
}
|
||||
|
||||
|
||||
// Helper:
|
||||
//
|
||||
// Check that an access to a HI/LO register meets timing requirements
|
||||
|
@ -340,6 +404,8 @@
|
|||
*vr5000:
|
||||
*r3900:
|
||||
{
|
||||
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
||||
{
|
||||
ALU32_BEGIN (GPR[RS]);
|
||||
|
@ -364,6 +430,8 @@
|
|||
*vr5000:
|
||||
*r3900:
|
||||
{
|
||||
if (NotWordValue (GPR[RS]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE));
|
||||
{
|
||||
ALU32_BEGIN (GPR[RS]);
|
||||
|
@ -377,6 +445,8 @@
|
|||
|
||||
:function:::void:do_addiu:int rs, int rt, unsigned16 immediate
|
||||
{
|
||||
if (NotWordValue (GPR[rs]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate));
|
||||
GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate));
|
||||
TRACE_ALU_RESULT (GPR[rt]);
|
||||
|
@ -402,6 +472,8 @@
|
|||
|
||||
:function:::void:do_addu:int rs, int rt, int rd
|
||||
{
|
||||
if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
|
||||
GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]);
|
||||
TRACE_ALU_RESULT (GPR[rd]);
|
||||
|
@ -558,6 +630,8 @@
|
|||
{
|
||||
address_word offset = EXTEND16 (OFFSET) << 2;
|
||||
check_branch_bug ();
|
||||
if (RS == 31)
|
||||
Unpredictable ();
|
||||
RA = (CIA + 8);
|
||||
if ((signed_word) GPR[RS] >= 0)
|
||||
{
|
||||
|
@ -582,6 +656,8 @@
|
|||
{
|
||||
address_word offset = EXTEND16 (OFFSET) << 2;
|
||||
check_branch_bug ();
|
||||
if (RS == 31)
|
||||
Unpredictable ();
|
||||
RA = (CIA + 8);
|
||||
/* NOTE: The branch occurs AFTER the next instruction has been
|
||||
executed */
|
||||
|
@ -762,6 +838,8 @@
|
|||
{
|
||||
address_word offset = EXTEND16 (OFFSET) << 2;
|
||||
check_branch_bug ();
|
||||
if (RS == 31)
|
||||
Unpredictable ();
|
||||
RA = (CIA + 8);
|
||||
/* NOTE: The branch occurs AFTER the next instruction has been
|
||||
executed */
|
||||
|
@ -788,6 +866,8 @@
|
|||
{
|
||||
address_word offset = EXTEND16 (OFFSET) << 2;
|
||||
check_branch_bug ();
|
||||
if (RS == 31)
|
||||
Unpredictable ();
|
||||
RA = (CIA + 8);
|
||||
if ((signed_word) GPR[RS] < 0)
|
||||
{
|
||||
|
@ -926,6 +1006,8 @@
|
|||
unsigned32 i, mask;
|
||||
if (RT != RD)
|
||||
Unpredictable ();
|
||||
if (NotWordValue (GPR[RS]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT1 (GPR[RS]);
|
||||
for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
|
||||
{
|
||||
|
@ -948,6 +1030,8 @@
|
|||
unsigned32 i, mask;
|
||||
if (RT != RD)
|
||||
Unpredictable ();
|
||||
if (NotWordValue (GPR[RS]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT1 (GPR[RS]);
|
||||
for (mask = ((unsigned32)1<<31), i = 0; i < 32; ++i)
|
||||
{
|
||||
|
@ -2099,6 +2183,8 @@
|
|||
{
|
||||
signed64 temp;
|
||||
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
|
||||
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
||||
temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
|
||||
+ ((signed64) EXTEND32 (GPR[RT]) * (signed64) EXTEND32 (GPR[RS])));
|
||||
|
@ -2116,6 +2202,8 @@
|
|||
{
|
||||
unsigned64 temp;
|
||||
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
|
||||
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
||||
temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
|
||||
+ ((unsigned64) VL4_8 (GPR[RS]) * (unsigned64) VL4_8 (GPR[RT])));
|
||||
|
@ -2212,6 +2300,8 @@
|
|||
{
|
||||
signed64 temp;
|
||||
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
|
||||
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
||||
temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
|
||||
- ((signed64) EXTEND32 (GPR[RT]) * (signed64) EXTEND32 (GPR[RS])));
|
||||
|
@ -2229,6 +2319,8 @@
|
|||
{
|
||||
unsigned64 temp;
|
||||
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
|
||||
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
||||
temp = (U8_4 (VL4_8 (HI), VL4_8 (LO))
|
||||
- ((unsigned64) VL4_8 (GPR[RS]) * (unsigned64) VL4_8 (GPR[RT])));
|
||||
|
@ -2283,6 +2375,8 @@
|
|||
*mips64:
|
||||
{
|
||||
signed64 prod;
|
||||
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
||||
prod = (((signed64)(signed32) GPR[RS])
|
||||
* ((signed64)(signed32) GPR[RT]));
|
||||
|
@ -2296,6 +2390,8 @@
|
|||
{
|
||||
signed64 prod;
|
||||
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
|
||||
if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
|
||||
prod = (((signed64)(signed32) GPR[rs])
|
||||
* ((signed64)(signed32) GPR[rt]));
|
||||
|
@ -2335,6 +2431,8 @@
|
|||
{
|
||||
unsigned64 prod;
|
||||
check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
|
||||
if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
|
||||
prod = (((unsigned64)(unsigned32) GPR[rs])
|
||||
* ((unsigned64)(unsigned32) GPR[rt]));
|
||||
|
@ -2893,6 +2991,8 @@
|
|||
:function:::void:do_sra:int rt, int rd, int shift
|
||||
{
|
||||
signed32 temp = (signed32) GPR[rt] >> shift;
|
||||
if (NotWordValue (GPR[rt]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[rt], shift);
|
||||
GPR[rd] = EXTEND32 (temp);
|
||||
TRACE_ALU_RESULT (GPR[rd]);
|
||||
|
@ -2920,6 +3020,8 @@
|
|||
{
|
||||
int s = MASKED (GPR[rs], 4, 0);
|
||||
signed32 temp = (signed32) GPR[rt] >> s;
|
||||
if (NotWordValue (GPR[rt]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[rt], s);
|
||||
GPR[rd] = EXTEND32 (temp);
|
||||
TRACE_ALU_RESULT (GPR[rd]);
|
||||
|
@ -2946,6 +3048,8 @@
|
|||
:function:::void:do_srl:int rt, int rd, int shift
|
||||
{
|
||||
unsigned32 temp = (unsigned32) GPR[rt] >> shift;
|
||||
if (NotWordValue (GPR[rt]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[rt], shift);
|
||||
GPR[rd] = EXTEND32 (temp);
|
||||
TRACE_ALU_RESULT (GPR[rd]);
|
||||
|
@ -2972,6 +3076,8 @@
|
|||
{
|
||||
int s = MASKED (GPR[rs], 4, 0);
|
||||
unsigned32 temp = (unsigned32) GPR[rt] >> s;
|
||||
if (NotWordValue (GPR[rt]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[rt], s);
|
||||
GPR[rd] = EXTEND32 (temp);
|
||||
TRACE_ALU_RESULT (GPR[rd]);
|
||||
|
@ -3007,6 +3113,8 @@
|
|||
*vr5000:
|
||||
*r3900:
|
||||
{
|
||||
if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
|
||||
{
|
||||
ALU32_BEGIN (GPR[RS]);
|
||||
|
@ -3019,6 +3127,8 @@
|
|||
|
||||
:function:::void:do_subu:int rs, int rt, int rd
|
||||
{
|
||||
if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
|
||||
Unpredictable ();
|
||||
TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
|
||||
GPR[rd] = EXTEND32 (GPR[rs] - GPR[rt]);
|
||||
TRACE_ALU_RESULT (GPR[rd]);
|
||||
|
|
|
@ -771,8 +771,9 @@ INLINE_SIM_MAIN (void) prefetch PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word
|
|||
#define Prefetch(CCA,pAddr,vAddr,DATA,hint) \
|
||||
prefetch (SD, CPU, cia, CCA, pAddr, vAddr, DATA, hint)
|
||||
|
||||
#define UndefinedResult()
|
||||
#define Unpredictable()
|
||||
void unpredictable_action (sim_cpu *cpu, address_word cia);
|
||||
#define NotWordValue(val) not_word_value (SD_, (val))
|
||||
#define Unpredictable() unpredictable (SD_)
|
||||
|
||||
INLINE_SIM_MAIN (unsigned32) ifetch32 PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, address_word vaddr));
|
||||
#define IMEM32(CIA) ifetch32 (SD, CPU, (CIA), (CIA))
|
||||
|
|
Loading…
Reference in New Issue