target-arm: allow modifying vfp fpexc en bit only
authorJuha Riihimäki <juha.riihimaki@nokia.com>
Mon, 26 Oct 2009 09:46:42 +0000 (11:46 +0200)
committerAurelien Jarno <aurelien@aurel32.net>
Tue, 27 Oct 2009 08:46:26 +0000 (09:46 +0100)
All other bits except for the EN in the VFP FPEXC register are defined
as subarchitecture specific and real functionality for any of the
other bits has not been implemented in QEMU. However, current code
allows modifying all bits in the VFP FPEXC register leading to
problems when guest code is writing 1's to the subarchitecture
specific bits and checking whether the bits stay up to verify the
existence of functionality which in fact does not exist in QEMU.
This patch has been revised to include the same behavior change in
the gdb register write function.

Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
Acked-by: Laurent Desnogues <laurent.desnogues@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
target-arm/helper.c
target-arm/translate.c

index 021d121df9c117215cff6e287bd78b4b8bdce8f8..5e10533f1c82c909638f1cca4ecb74a4697390f9 100644 (file)
@@ -234,7 +234,7 @@ static int vfp_gdb_set_reg(CPUState *env, uint8_t *buf, int reg)
     switch (reg - nregs) {
     case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
     case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4;
-    case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf); return 4;
+    case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
     }
     return 0;
 }
index f0ebf4fad60c7b2b9a1d3059511b931a38e15cf5..70cf1b268afc96e69fdcdd5221f1c8beba98ff75 100644 (file)
@@ -2788,6 +2788,9 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         case ARM_VFP_FPEXC:
                             if (IS_USER(s))
                                 return 1;
+                            /* TODO: VFP subarchitecture support.
+                             * For now, keep the EN bit only */
+                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
                             store_cpu_field(tmp, vfp.xregs[rn]);
                             gen_lookup_tb(s);
                             break;