|
From: | G 3 |
Subject: | Re: [Qemu-ppc] [Qemu-devel] [PATCH] fix fdiv instruction |
Date: | Tue, 26 Jun 2018 15:50:39 -0400 |
On Jun 26, 2018, at 9:49 AM, Richard Henderson wrote:
On 06/25/2018 03:23 PM, Programmingkid wrote:On Jun 25, 2018, at 5:08 PM, Richard Henderson <address@hidden> wrote:On Mon, Jun 25, 2018, 08:23 G 3 <address@hidden> wrote:Try uint64_t expected_answer = 0xffff0000deadbeef; ... c.i = expected_answer;asm volatile("fdiv %0, %1, %2" : "+f"(c.d) : "f"(1.0), "f"(0.0));to avoid depending on uninitialized data. (This expected value is an SNaN with a deadbeef marker Just to be Sure.) r~Ok I made this program and tried it on my iMac G5 (PowerPC 970). #include <stdio.h> #include <stdint.h> #include <inttypes.h> // Used to convert unsigned integer <--> double union Converter { double d; uint64_t i; }; typedef union Converter Converter; int main (int argc, const char * argv[]) { Converter answer; answer.i = 0xffff0000deadbeef; //asm volatile("mtfsb1 27"); /* Set ZE bit */ asm volatile("fdiv %0, %1, %2" : "=f"(answer.d) : "f"(1.0), "f"(0.0)); Need +f for inout operand. This didn't test what you expected.What do you mean by inout operand?An operand that is both input and output.If you could send me some sample code I will test it out.I did, you just didn't read it properly. Here it is again: asm volatile("fdiv %0, %1, %2" : "+f"(answer.d) : "f"(1.0), "f"(0.0)); ^^^^ r~
I used the +f constraint and did see different results. Computer used was an iMac G5 (PowerPC 970).
If FPSCR[ZE] is set: answer = 0xffff0000deadbeef (changed from 0x0) if FPSCR[ZE] is not set: answer = 0x7ff0000000000000 (no change from before)I then tried this program in QEMU without any of my patches applied. Here is the result:
If FPSCR[ZE] is set or not set, answer = 0x7ff0000000000000. This indicates to me that the fdiv instruction needs a little work. This is what I think should happen. If division by zero takes place and the FPSCR[ZE] bit is set, then the value in the destination register should not be altered (rather than returning zero).
Here is the program used: #include <stdio.h> #include <stdint.h> #include <inttypes.h> // Used to convert unsigned integer <--> double union Converter { double d; uint64_t i; }; typedef union Converter Converter; int main (int argc, const char * argv[]) { Converter answer; answer.i = 0xffff0000deadbeef; //asm volatile("mtfsb1 27"); /* Set ZE bit */asm volatile("fdiv %0, %1, %2" : "+f"(answer.d) : "f"(1.0), "f"(0.0));
printf("answer = 0x%" PRIx64 "\n", answer.i); return 0; }
[Prev in Thread] | Current Thread | [Next in Thread] |