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