* [Qemu-devel] PATCH stfiwx implementation
@ 2006-10-10 9:10 Tom Marn
2006-10-11 8:05 ` Tom Marn
0 siblings, 1 reply; 5+ messages in thread
From: Tom Marn @ 2006-10-10 9:10 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 720 bytes --]
Hi
This is the patch which appends optional "stfiwx" PowerPC instruction into QEMU. For demonstration purpose you can use attached stfiwx_cast.c code. But i'm still having problems with "gen_op_load_fpr_FT1(rS(ctx->opcode));" macro which loads fpr[rS(ctx->opcode] into internal FT1 register. When the value of parameter is in the correct range (0 - 31), data from the selected fpr register is not transfered into FT1, but when we manually change the value to the wrong range (for example 32, gen_op_load_fpr_FT1(32) ) the FT1 gets the correct value, strange. I guess, because the qemu micro instruction couldn't be found (gen_op_load_fpr_FT1_fpr32) something flushed the fpr registers to the correct values.
Tom Marn
[-- Attachment #2: stfiwx_cast.patch --]
[-- Type: text/x-patch, Size: 3407 bytes --]
Patch which appends optional "stfiwx" PowerPC instruction into QEMU.
Tom Marn
--- qemu/target-ppc/translate.c.orig 2006-10-10 08:59:30.000000000 +0200
+++ qemu/target-ppc/translate.c 2006-10-10 09:42:26.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_FT1(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-10 08:59:45.000000000 +0200
+++ qemu/target-ppc/op_mem.h 2006-10-10 09:18:39.000000000 +0200
@@ -187,6 +187,23 @@ 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, double d)
+{
+
+ union {
+ double d;
+ uint32_t u;
+ } u;
+
+ u.d = d;
+ u.u = u.u && 0x00000000FFFFFFFFULL;
+ glue(stl, MEMSUFFIX)(T0, u.d);
+ RETURN();
+
+}
+
+PPC_STF_OP(fi, stfi);
+
static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
{
union {
@@ -224,6 +241,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)) \
[-- Attachment #3: stfiwx_cast.c --]
[-- Type: text/x-csrc, Size: 415 bytes --]
/* PowerPC testing code for my implementation of optional stfiwx
* instruction implemented for QEMU. Casting from float to integer
* will produce "stfiwx" call.
* Tested on PPC 603e
* Tom Marn
*/
#include <stdio.h>
int stfiwx_cast(float f)
{
int i;
i = (int)f;
printf("float: %f [0x%08x] -> integer: %i [0x%08x]\n", f, *((unsigned int *)&f), i, i);
return i;
}
int main()
{
stfiwx_cast(22.316447);
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] PATCH stfiwx implementation
2006-10-10 9:10 [Qemu-devel] PATCH stfiwx implementation Tom Marn
@ 2006-10-11 8:05 ` Tom Marn
2006-10-16 8:23 ` [Qemu-devel] PATCH stfiwx implementation - Problem with casting Tom Marn
0 siblings, 1 reply; 5+ messages in thread
From: Tom Marn @ 2006-10-11 8:05 UTC (permalink / raw)
To: tom.marn, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 114 bytes --]
Hi
Resending fixed patch, mirror fix in glue(stfi, MEMSUFFIX) function; bitwise typo: && instead of &.
Tom Marn
[-- Attachment #2: stfiwx_cast.patch --]
[-- Type: text/x-patch, Size: 3582 bytes --]
Patch which appends optional "stfiwx" PowerPC instruction into QEMU.
Mirror fix of patch: 2006-10-11 : bitwise typo && instead &
Tom Marn
--- target-ppc/translate.c.orig 2006-10-11 09:05:17.000000000 +0200
+++ target-ppc/translate.c 2006-10-11 09:56:02.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_FT1(rS(ctx->opcode)); \
+ op_ldst(st##width); \
+}
+
+#define GEN_STFI(width) \
+OP_ST_TABLE(width); \
+GEN_STWXF(width);
+
+GEN_STFI(fi);
/*** Branch ***/
--- target-ppc/op_mem.h.orig 2006-10-11 09:05:28.000000000 +0200
+++ target-ppc/op_mem.h 2006-10-11 09:52:28.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)) \
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] PATCH stfiwx implementation - Problem with casting
2006-10-11 8:05 ` Tom Marn
@ 2006-10-16 8:23 ` Tom Marn
2006-10-16 19:58 ` André Braga
0 siblings, 1 reply; 5+ messages in thread
From: Tom Marn @ 2006-10-16 8:23 UTC (permalink / raw)
To: tom.marn, qemu-devel
[-- Attachment #1: Type: text/plain, Size: 919 bytes --]
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
[-- Attachment #2: cast_ftoi.c --]
[-- Type: text/x-csrc, Size: 508 bytes --]
#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();
}
[-- Attachment #3: stfiwx_cast.patch --]
[-- Type: text/x-patch, Size: 3690 bytes --]
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)) \
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] PATCH stfiwx implementation - Problem with casting
2006-10-16 8:23 ` [Qemu-devel] PATCH stfiwx implementation - Problem with casting Tom Marn
@ 2006-10-16 19:58 ` André Braga
2006-10-17 7:52 ` Tom Marn
0 siblings, 1 reply; 5+ messages in thread
From: André Braga @ 2006-10-16 19:58 UTC (permalink / raw)
To: qemu-devel
On 10/16/06, Tom Marn <tom.marn@telargo.com> wrote:
> cast test 1 - float: 85.745110 [0x42ab7d7f] -> integer: 85 [0x00000055]
> cast test 2 - float: 85.745110 [0x42ab7d7f] -> integer: 57005 [0x0000dead] <-- 85 is correct
Am I the only one who found this result EXTREMELY amusing? :D
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] PATCH stfiwx implementation - Problem with casting
2006-10-16 19:58 ` André Braga
@ 2006-10-17 7:52 ` Tom Marn
0 siblings, 0 replies; 5+ messages in thread
From: Tom Marn @ 2006-10-17 7:52 UTC (permalink / raw)
To: qemu-devel
André Braga wrote:
> On 10/16/06, Tom Marn wrote:
>> cast test 1 - float: 85.745110 [0x42ab7d7f] -> integer: 85 [0x00000055]
>> cast test 2 - float: 85.745110 [0x42ab7d7f] -> integer: 57005
>> [0x0000dead] <-- 85 is correct
>
> Am I the only one who found this result EXTREMELY amusing? :D
>
Thanks André
This is the purpose to attract the eye to my problem. At least you spend some time on it, to find it amusing too. ;)
Now I have the hope that the problem also could be solved.I can send log files of Qemu VM instructions for both tests.
Any ideas?
Tom
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-10-17 7:52 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-10 9:10 [Qemu-devel] PATCH stfiwx implementation Tom Marn
2006-10-11 8:05 ` Tom Marn
2006-10-16 8:23 ` [Qemu-devel] PATCH stfiwx implementation - Problem with casting Tom Marn
2006-10-16 19:58 ` André Braga
2006-10-17 7:52 ` Tom Marn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).