Patchwork [30/60] MIPS: Correct FCR0 initialization

login
register
mail settings
Submitter Michael Tokarev
Date Feb. 4, 2013, 10:40 a.m.
Message ID <1359974470-17044-31-git-send-email-mjt@msgid.tls.msk.ru>
Download mbox | patch
Permalink /patch/218022/
State New
Headers show

Comments

Michael Tokarev - Feb. 4, 2013, 10:40 a.m.
From: Nathan Froyd <froydnj@codesourcery.com>

 This change addresses a problem where QEMU incorrectly traps on
floating-point MADD group instructions with SIGILL, at least while
emulating MIPS32r2 processors.  These instructions use the COP1X major
opcode and include ones like:

	madd.d	$f2,$f4,$f2,$f6

 Here's Nathan's original analysis of the problem:

"QEMU essentially does:

  d = find_cpu (cpu_string)	// get CPU definition
  fpu_init (env, d)		// initialize fpu state (init FCR0, basically)
  cpu_reset (env)

...and the cpu_reset call clears all interesting state that fpu_init
setup, then proceeds to reinitialize all the CP0 registers...but not
FCR0."

 I have verified this change with system emulation running the GDB test
suite for the mips-sde-elf target (o32, big endian, 24Kf CPU emulated),
there were 55 progressions and no regressions.

Signed-off-by: Maciej W. Rozycki <macro@codesourcery.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
(cherry picked from commit f1cb0951c5298753652a73cfd8efc0b1a82f37de)

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
---
 target-mips/translate.c |    1 +
 1 file changed, 1 insertion(+)

Patch

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 5ed58f6..8ff1fab 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12783,6 +12783,7 @@  void cpu_state_reset(CPUMIPSState *env)
     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
+    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
     env->insn_flags = env->cpu_model->insn_flags;
 
 #if defined(CONFIG_USER_ONLY)