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))                                        \
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to