|
| From: | G 3 |
| Subject: | Re: [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] |