qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] PATCH stfiwx implementation - Problem with casting


From: Tom Marn
Subject: Re: [Qemu-devel] PATCH stfiwx implementation - Problem with casting
Date: Mon, 16 Oct 2006 10:23:32 +0200
User-agent: Thunderbird 1.5.0.2 (X11/20060516)

Please use last attached patch for stfiwx implementation and demonstration of 
cast problem. Instruction stfiwx is used when casting from float point to 
integer is needed.

I'm having problems with proper evaluation of values at the line (in cast_ftoi.c) where 
casting from float to integer accured. In first example where evaluation is separated 
from casting there is no problems, but in second example instead of evaluated value the 
last parameter "b" is casted to integer (like lazy evaluation), that's wrong. 
(see cast_ftoi.c) Is there maybe a problem with generating the correct qemu vm 
instructions. The casting has been tested on real powerpc 603e processor board where 
casting works properly and on Qemu where second test fails.

cast test 1 - float: 85.745110 [0x42ab7d7f] -> integer: 85 [0x00000055]
cast test 2 - float: 85.745110 [0x42ab7d7f] -> integer: 57005 [0x0000dead] <-- 
85 is correct

Tom Marn







#include <stdio.h>

int cast_ftoi()
{
        int a = 0xBEEF;
        int b = 0xDEAD;

        int     i1,i2;
        float   f1,f2;
        
        __asm__ __volatile__ ("nop");

        f1 = (100.0 * a / b);
        i1 = f1;
        
        __asm__ __volatile__ ("nop");

        i2 = (100.0 * a / b);
        
        __asm__ __volatile__ ("nop");

         printf("cast test 1 - float: %f [0x%08x] -> integer: %i [0x%08x]\n", 
f1, *((unsigned int *)&f1), i1, i1);
         printf("cast test 2 - float: %f [0x%08x] -> integer: %i [0x%08x]\n", 
f1, *((unsigned int *)&f1), i2, i2);

}

int main()
{
        cast_ftoi();
}
Patch which appends optional "stfiwx" PowerPC instruction into QEMU.
Mirror fix of patch: 
 
 2006-10-11 :  bitwise typo && instead &
 2006-10-16 :  using FT0 instead of FT1, but still having problem with casting

Tom Marn

--- qemu/target-ppc/translate.c.orig    2006-10-16 09:58:32.000000000 +0200
+++ qemu/target-ppc/translate.c 2006-10-16 10:04:04.000000000 +0200
@@ -1716,14 +1716,29 @@ GEN_STFS(fs, 0x14);
 
 /* Optional: */
 /* stfiwx */
-GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
-{
-    if (!ctx->fpu_enabled) {
-        RET_EXCP(ctx, EXCP_NO_FP, 0);
-        return;
-    }
-    RET_INVAL(ctx);
-}
+#define GEN_STWXF(width)                                                      \
+GEN_HANDLER(st##width##wx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)           \
+{                                                                             \
+    if (!ctx->fpu_enabled) {                                                  \
+        RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
+        return;                                                               \
+    }                                                                         \
+    if (rA(ctx->opcode) == 0) {                                               \
+        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
+    } else {                                                                  \
+        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
+        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
+        gen_op_add();                                                         \
+    }                                                                         \
+    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
+    op_ldst(st##width);                                                       \
+}
+
+#define GEN_STFI(width)                                                       \
+OP_ST_TABLE(width);                                                           \
+GEN_STWXF(width);
+
+GEN_STFI(fi);
 
 /***                                Branch                                 ***/
 
--- qemu/target-ppc/op_mem.h.orig       2006-10-16 10:00:28.000000000 +0200
+++ qemu/target-ppc/op_mem.h    2006-10-16 10:03:30.000000000 +0200
@@ -187,6 +187,30 @@ PPC_OP(glue(glue(st, name), MEMSUFFIX)) 
 PPC_STF_OP(fd, stfq);
 PPC_STF_OP(fs, stfl);
 
+
+static inline void glue(stfi, MEMSUFFIX) (target_ulong EA, float f)
+{
+    union {
+        float f;
+        uint32_t u;
+    } u;
+
+    u.f = f;
+    u.u = u.u & 0x00000000FFFFFFFFULL;
+    glue(stl, MEMSUFFIX)(T0, u.f);
+    RETURN();
+}
+
+#if 0
+static inline void glue(stfi, MEMSUFFIX) (target_ulong EA, float f)
+{
+       glue(stl, MEMSUFFIX)(T0,(int)f);
+       RETURN();
+}
+#endif
+
+PPC_STF_OP(fi, stfi);
+
 static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
 {
     union {
@@ -224,6 +248,23 @@ static inline void glue(stflr, MEMSUFFIX
 PPC_STF_OP(fd_le, stfqr);
 PPC_STF_OP(fs_le, stflr);
 
+static inline void glue(stfir, MEMSUFFIX) (target_ulong EA, float f)
+{
+       union {
+        float f;
+        uint32_t u;
+    } u;
+
+       u.f = f;
+    u.u = ((u.u & 0xFF000000UL) >> 24) |
+        ((u.u & 0x00FF0000ULL) >> 8) |
+        ((u.u & 0x0000FF00UL) << 8) |
+        ((u.u & 0x000000FFULL) << 24);
+    glue(stfi, MEMSUFFIX)(EA, u.f);
+}
+
+PPC_STF_OP(fi_le, stfir);
+
 /***                         Floating-point load                           ***/
 #define PPC_LDF_OP(name, op)                                                  \
 PPC_OP(glue(glue(l, name), MEMSUFFIX))                                        \

reply via email to

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