[Top][All Lists]
[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)) \