Skip to contentSkip to conversation

Fix mov[tf].ps handling for MIPS

PATCH New Richard Sandiford 1 participant 1 message May 24, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix mov[tf].ps handling for MIPS

    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

target-mips/op.c +6 -4
Index: qemu/target-mips/op.c
===================================================================
@@ -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();
 }
target-mips/translate.c +4 -2
Index: qemu/target-mips/translate.c
===================================================================
@@ -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";