qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] Fix mov[tf].ps handling for MIPS


From: Richard Sandiford
Subject: [Qemu-devel] [PATCH] Fix mov[tf].ps handling for MIPS
Date: Sat, 24 May 2008 12:03:41 +0100
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/22.1 (gnu/linux)

    MOVT.PS $fd, $fs, $fccX

is curently treated like MOV*.D and MOV*.S; it moves $fs into $fd
if $fccX is true.  But the instruction actually moves each float
element separately; the lower move is conditional on $fccX and
the upper one is conditional on $fccX+1.  Same for MOVF.PS.

The patch below seems to work for me.  Please install if OK.

(I realise the MOVCF.FMT stuff ought to be TCG-ified eventually,
but hopefully this patch is strict progress.)

Richard


Index: qemu/target-mips/op.c
===================================================================
--- qemu.orig/target-mips/op.c  2008-05-24 09:33:33.000000000 +0100
+++ qemu/target-mips/op.c       2008-05-24 09:35:11.000000000 +0100
@@ -1632,10 +1632,11 @@ FLOAT_OP(movf, s)
 }
 FLOAT_OP(movf, ps)
 {
-    if (!(env->fpu->fcr31 & PARAM1)) {
+    unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1;
+    if (!(mask & 1))
         WT2 = WT0;
+    if (!(mask & 2))
         WTH2 = WTH0;
-    }
     DEBUG_FPU_STATE();
     FORCE_RET();
 }
@@ -1655,10 +1656,11 @@ FLOAT_OP(movt, s)
 }
 FLOAT_OP(movt, ps)
 {
-    if (env->fpu->fcr31 & PARAM1) {
+    unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1;
+    if (mask & 1)
         WT2 = WT0;
+    if (mask & 2)
         WTH2 = WTH0;
-    }
     DEBUG_FPU_STATE();
     FORCE_RET();
 }
Index: qemu/target-mips/translate.c
===================================================================
--- qemu.orig/target-mips/translate.c   2008-05-24 09:35:37.000000000 +0100
+++ qemu/target-mips/translate.c        2008-05-24 11:05:46.000000000 +0100
@@ -5592,7 +5592,6 @@ static void glue(gen_movcf_, fmt) (Disas
 }
 GEN_MOVCF(d);
 GEN_MOVCF(s);
-GEN_MOVCF(ps);
 #undef GEN_MOVCF
 
 static void gen_farith (DisasContext *ctx, uint32_t op1,
@@ -6211,7 +6210,10 @@ static void gen_farith (DisasContext *ct
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
         GEN_LOAD_FREG_FTN(WTH2, fd);
-        gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
+        if (ft & 0x1)
+            gen_op_float_movt_ps ((ft >> 2) & 0x7);
+        else
+            gen_op_float_movf_ps ((ft >> 2) & 0x7);
         GEN_STORE_FTN_FREG(fd, WT2);
         GEN_STORE_FTN_FREG(fd, WTH2);
         opn = "movcf.ps";




reply via email to

[Prev in Thread] Current Thread [Next in Thread]