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:
Chris Demetriou 2002-05-01 17:26:14 +00:00
parent a6befae84d
commit 402586aa26
5 changed files with 153 additions and 26 deletions

View File

@ -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().

View File

@ -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 ()");

View File

@ -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 ------------------------------------------*/

View File

@ -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]);

View File

@ -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))