This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[applied mips sim patch] Add UNPREDICTABLE checking for manyops.
- From: cgd at broadcom dot com
- To: gdb-patches at sources dot redhat dot com
- Date: 01 May 2002 10:26:13 -0700
- Subject: [applied mips sim patch] Add UNPREDICTABLE checking for manyops.
The following patch adds checking for UNPREDICTABLE behaviour to many
instruction operations in the MIPS simulator, as per the MIPS64 ISA
spec.
I coded the patch so that for existing targets other than MIPS32 and
MIPS64, the new code checking for unpredictable behaviour should have
no effect.
I verified that a whole bunch of mips simulators still build, just to
make sure i didn't introduce a syntax error on some platform that i
wouldn't normally test. 8-)
Further, I verified using check-gcc for a tweaked configuration
(mipsisa32-elf, but with simulator generating a mips64 sim and the
tests run for the -mips64 multilib) that these produced the expected
amount of breakage: some (27) GCC tests now rightly fail due to
unpredictable behaviour caused by invalid operands to 32-bit ALU
operations (specifically addiu). Further information about the GCC
problem can be found in: GCC PR 5625.
chris
==========================================
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.
Index: cp1.c
===================================================================
RCS file: /cvs/src/src/sim/mips/cp1.c,v
retrieving revision 1.4
diff -u -p -r1.4 cp1.c
--- cp1.c 20 Mar 2002 07:24:20 -0000 1.4
+++ cp1.c 1 May 2002 17:18:51 -0000
@@ -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 ()");
Index: interp.c
===================================================================
RCS file: /cvs/src/src/sim/mips/interp.c,v
retrieving revision 1.11
diff -u -p -r1.11 interp.c
--- interp.c 20 Apr 2002 16:39:46 -0000 1.11
+++ interp.c 1 May 2002 17:18:51 -0000
@@ -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 ------------------------------------------*/
Index: mips.igen
===================================================================
RCS file: /cvs/src/src/sim/mips/mips.igen,v
retrieving revision 1.37
diff -u -p -r1.37 mips.igen
--- mips.igen 25 Apr 2002 05:37:03 -0000 1.37
+++ mips.igen 1 May 2002 17:18:51 -0000
@@ -144,6 +144,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
//
// The following requirements exist:
@@ -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]);
Index: sim-main.h
===================================================================
RCS file: /cvs/src/src/sim/mips/sim-main.h,v
retrieving revision 1.11
diff -u -p -r1.11 sim-main.h
--- sim-main.h 6 Mar 2002 06:46:29 -0000 1.11
+++ sim-main.h 1 May 2002 17:18:52 -0000
@@ -771,8 +771,9 @@ INLINE_SIM_MAIN (void) prefetch PARAMS (
#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))