Patchwork [v2,4/8] SPARC64: fp_disabled checks on stfa/stdfa/stqfa

login
register
mail settings
Submitter Tsuneo Saito
Date July 14, 2011, 9:41 a.m.
Message ID <1310636503-8956-5-git-send-email-tsnsaito@gmail.com>
Download mbox | patch
Permalink /patch/104660/
State New
Headers show

Comments

Tsuneo Saito - July 14, 2011, 9:41 a.m.
stfa/stdfa/stqfa instructions should raise fp_disabled exceptions
if %pstate.PEF==0 or %fprs.FEF==0.

Signed-off-by: Tsuneo Saito <tsnsaito@gmail.com>
---
 target-sparc/translate.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)
Peter Maydell - July 14, 2011, 10:39 a.m.
On 14 July 2011 10:41, Tsuneo Saito <tsnsaito@gmail.com> wrote:
> stfa/stdfa/stqfa instructions should raise fp_disabled exceptions
> if %pstate.PEF==0 or %fprs.FEF==0.

Not really related to this patch but I happened to notice it:
we generate a trap if dc->fpu_enabled is clear. That flag is set with:
        dc->fpu_enabled = cpu_fpu_enabled(env);
which looks at the CPUState passed into gen_intermediate_code_internal.

I think it should be pulling the fpu-enabled state out of the
tb->flags instead. Otherwise you'll have problems if you have
a TB with (1) a trap-if-no-fpu insn (2) a change of the fpu-enabled
state (3) a load/store that faults.

-- PMM
Blue Swirl - July 14, 2011, 3:33 p.m.
On Thu, Jul 14, 2011 at 1:39 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 14 July 2011 10:41, Tsuneo Saito <tsnsaito@gmail.com> wrote:
>> stfa/stdfa/stqfa instructions should raise fp_disabled exceptions
>> if %pstate.PEF==0 or %fprs.FEF==0.
>
> Not really related to this patch but I happened to notice it:
> we generate a trap if dc->fpu_enabled is clear. That flag is set with:
>        dc->fpu_enabled = cpu_fpu_enabled(env);
> which looks at the CPUState passed into gen_intermediate_code_internal.
>
> I think it should be pulling the fpu-enabled state out of the
> tb->flags instead. Otherwise you'll have problems if you have
> a TB with (1) a trap-if-no-fpu insn (2) a change of the fpu-enabled
> state (3) a load/store that faults.

Nice catch, this also affects Sparc32.
Blue Swirl - July 14, 2011, 5:56 p.m.
On Thu, Jul 14, 2011 at 1:39 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 14 July 2011 10:41, Tsuneo Saito <tsnsaito@gmail.com> wrote:
>> stfa/stdfa/stqfa instructions should raise fp_disabled exceptions
>> if %pstate.PEF==0 or %fprs.FEF==0.
>
> Not really related to this patch but I happened to notice it:
> we generate a trap if dc->fpu_enabled is clear. That flag is set with:
>        dc->fpu_enabled = cpu_fpu_enabled(env);
> which looks at the CPUState passed into gen_intermediate_code_internal.
>
> I think it should be pulling the fpu-enabled state out of the
> tb->flags instead. Otherwise you'll have problems if you have
> a TB with (1) a trap-if-no-fpu insn (2) a change of the fpu-enabled
> state (3) a load/store that faults.

I applied a patch to fix this and similar bug with AM bit.

Patch

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index a5a8eaf..5f92dbb 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -4732,6 +4732,9 @@  static void disas_sparc_insn(DisasContext * dc)
                 switch (xop) {
 #ifdef TARGET_SPARC64
                 case 0x34: /* V9 stfa */
+                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
+                        goto jmp_insn;
+                    }
                     gen_stf_asi(cpu_addr, insn, 4, rd);
                     break;
                 case 0x36: /* V9 stqfa */
@@ -4739,6 +4742,9 @@  static void disas_sparc_insn(DisasContext * dc)
                         TCGv_i32 r_const;
 
                         CHECK_FPU_FEATURE(dc, FLOAT128);
+                        if (gen_trap_ifnofpu(dc, cpu_cond)) {
+                            goto jmp_insn;
+                        }
                         r_const = tcg_const_i32(7);
                         gen_helper_check_align(cpu_addr, r_const);
                         tcg_temp_free_i32(r_const);
@@ -4746,6 +4752,9 @@  static void disas_sparc_insn(DisasContext * dc)
                     }
                     break;
                 case 0x37: /* V9 stdfa */
+                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
+                        goto jmp_insn;
+                    }
                     gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
                     break;
                 case 0x3c: /* V9 casa */