Re: [Qemu-devel] Floating point unit bugs
Here is version two of the floating point test program: / ** * File: main.c * Date: 4-30-2017 * Description: Implement a test program for various floating point instructions. * Note: tests made to work with PowerPC G3 and G5 only. * Compiling on Mac OS X: use gcc-3.3 -force_cpusubtype_ALL * Note: fsqrt test will not work on PowerPC G3. * Version: 2 **/ #include #include #include #include #include // Used to convert unsigned integer <--> double union Converter { double d; uint64_t i; }; typedef union Converter Converter; /* Describes the name and description of each bit of the FPSCR */ struct fpscr_info { char name[8]; char description[100]; }; struct fpscr_info finfo[] = { "FX", "Floating-point exception summary", "FEX", "Floating-point enabled exception summary", "VX", "Floating-point invalid operation exception summary", "OX", "Floating-point overflow exception", "UX", "Floating-point underflow exception", "ZX", "Floating-point zero divide exception", "XX", "Floating-point inexact exception", "VXSNAN", "Floating-point invalid operation exception for SNaN", "VXISI", "Floating-point invalid operation exception for ∞ - ∞", "VXIDI", "Floating-point invalid operation exception for ∞/∞", "VXZDZ", "Floating-point invalid operation exception for 0/0", "VXIMZ", "Floating-point invalid operation exception for ∞ * 0", "VXVC", "Floating-point invalid operation exception for invalid compare", "FR", "Floating-point fraction rounded", "FI", "Floating-point fraction inexact", "FPRF", "Floating-point result class descriptor ", "FPRF", "Floating-point less than or negative", "FPRF", "Floating-point greater than or positive", "FPRF", "Floating-point equal or zero", "FPRF", "Floating-point unordered or NaN", "NO NAME", "Reserved - you shouldn't be seeing this", "VXSOFT", "Floating-point invalid operation exception for software request", "VXSQRT", "Floating-point invalid operation exception for invalid square root", "VXCVI", "Floating-point invalid operation exception for invalid integer convert", "VE", "Floating-point invalid operation exception enable", "OE", "IEEE floating-point overflow exception enable", "UE", "IEEE floating-point underflow exception enable", "ZE", "IEEE floating-point zero divide exception enable", "XE", "Floating-point inexact exception enable", "NI", "Floating-point non-IEEE mode", "RN", "Rounding bit 0", "RN", "Rounding bit 1", }; // Prints all the FPSCR settings that are set in the input void print_fpscr_settings(uint32_t fpscr) { int i; for (i = 0; i < 32; i++) { if ((fpscr >> i) & 0x1 == 1) { /* right description = 31 - i Oddity of IBM documentation */ printf("bit %d: %s - %s\n", 31-i, finfo[31-i].name, finfo [31-i].description); } } } #define ZE 27 #define set_fpscr_bit(x) asm volatile ("mtfsb1 %0" : : "i"(x)) /* Keeps track of the number of tests that failed */ int failed_tests = 0; // Reset the FPSCR void reset_fpscr() { asm volatile("mtfsb0 0"); asm volatile("mtfsb0 1"); asm volatile("mtfsb0 2"); asm volatile("mtfsb0 3"); asm volatile("mtfsb0 4"); asm volatile("mtfsb0 5"); asm volatile("mtfsb0 6"); asm volatile("mtfsb0 7"); asm volatile("mtfsb0 8"); asm volatile("mtfsb0 9"); asm volatile("mtfsb0 10"); asm volatile("mtfsb0 11"); asm volatile("mtfsb0 12"); asm volatile("mtfsb0 13"); asm volatile("mtfsb0 14"); asm volatile("mtfsb0 15"); asm volatile("mtfsb0 16"); asm volatile("mtfsb0 17"); asm volatile("mtfsb0 18"); asm volatile("mtfsb0 19"); asm volatile("mtfsb0 20"); asm volatile("mtfsb0 21"); asm volatile("mtfsb0 22"); asm volatile("mtfsb0 23"); asm volatile("mtfsb0 24"); asm volatile("mtfsb0 25"); asm volatile("mtfsb0 26"); asm volatile("mtfsb0 27"); asm volatile("mtfsb0 28"); asm volatile("mtfsb0 29"); asm volatile("mtfsb0 30"); asm volatile("mtfsb0 31"); /* Check if everything is alright */ uint32_t fpscr; Converter c; asm volatile("mffs %0" : "=f"(c.d)); fpscr = (uint32_t)c.i; if (fpscr != 0) { printf("Warning: fpscr not equal to zero: 0x%x\n", fpscr); } } /* * The action to take if a test fails * Input one: message string * Input two: actual fpscr value * Input three: expected fpscr value * Input four: actual answer * Input five: expected answer */ void test_failed(const char *message, uint32_t actual_fpscr, uint32_t expected_fpscr, uint64_t actual_answer, uint64_t expected_answer) { printf("%s\n", message); printf("expected answer: 0x%" PRIx64 " (%f)\n", expected_answer,
Re: [Qemu-devel] Floating point unit bugs
On 2017-05-08 18:36, G 3 wrote: > > On May 8, 2017, at 6:13 PM, Aurelien Jarno wrote: > > > On 2017-05-07 17:48, G 3 wrote: > > > I made a diagnostic program for the floating point unit. It will test > > > various PowerPC floating point instructions for compatibility with > > > the > > > PowerPC G3 processor. It was tested on a PowerPC G3 and G5 system. > > > The > > > results of the program in qemu-system-ppc were pretty bad. About > > > every > > > instruction tested is not implemented correctly. > > > > > > Here is the download link to the program: > > > http://www.mediafire.com/file/6j9tqubvk73lkw1/floating_point_test_program.zip > > > > Some comments on the code. > > > > > > /* Check if everything is alright */ > > > uint32_t fpscr; > > > asm volatile("mffs f0"); > > > asm volatile("stfd f0, 40(r1)"); > > > asm volatile("lwz %0, 44(r1)" : "=r"(fpscr)); > > > if (fpscr != 0) { > > > printf("Warning: fpscr not equal to zero: 0x%x\n", fpscr); > > > } > > > > This is overly complicated and just doesn't compile with recent GCC > > versions. > > Which version of GCC had the problem? GCC 5.2 and GCC 3.3 seems to work > fine. GCC 4.0 did not work. Could you send me the error message? I tried with GCC 4.9. Actually the error message is coming from binutils: | main.c:34:5: warning: missing braces around initializer [-Wmissing-braces] | "FX", "Floating-point exception summary", | ^ | main.c:34:5: warning: (near initialization for 'finfo[0]') [-Wmissing-braces] | main.c: In function 'print_fpscr_settings': | main.c:73:26: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses] | if ((fpscr >> i) & 0x1 == 1) { | ^ | main.c: In function 'test_failed': | main.c:146:5: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 2 has type 'uint32_t' [-Wformat=] | printf(" actual answer: 0x%" PRIx64 "\n", actual_fpscr); | ^ | /tmp/cctHPRx4.s: Assembler messages: | /tmp/cctHPRx4.s:315: Error: unsupported relocation against f0 | /tmp/cctHPRx4.s:318: Error: unsupported relocation against f0 | /tmp/cctHPRx4.s:318: Error: unsupported relocation against r1 | /tmp/cctHPRx4.s:321: Error: unsupported relocation against r1 | /tmp/cctHPRx4.s:438: Error: unsupported relocation against f0 | /tmp/cctHPRx4.s:441: Error: unsupported relocation against f0 | /tmp/cctHPRx4.s:441: Error: unsupported relocation against r1 | /tmp/cctHPRx4.s:444: Error: unsupported relocation against r1 > > What about something like: > > > > Converter c; > > asm volatile("mffs %0" : "=f"(c.d)); > > fpscr = (uint32_t)c.i; > > This way does work also. > > > > > > > > /* > > > * The action to take if a test fails > > > * Input one: message string > > > * Input two: actual fpscr value > > > * Input three: expected fpscr value > > > * Input four: actual answer > > > * Input five: expected answer > > > */ > > > void test_failed(const char *message, uint32_t actual_fpscr, > > > uint32_t > > > expected_fpscr, > > > uint64_t actual_answer, uint64_t expected_answer) > > > { > > > printf("%s\n", message); > > > printf("expected answer: 0x%" PRIx64 "\n", expected_answer); > > > printf(" actual answer: 0x%" PRIx64 "\n", actual_fpscr); > > > > This is wrong. It should be actual_answer instead of actual_fpscr. That > > is why all the instructions seems totally wrongly implemented. > > Thanks for catching this error. Actually this would only effect the "actual > answer:" output field. The comparison between expected_answer and > actual_answer in each individual test is still valid. Indeed, but I guess it gives "better" results than what it looks when looking at your mail where the values are totally wrong. -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] Floating point unit bugs
On May 8, 2017, at 6:13 PM, Aurelien Jarno wrote: On 2017-05-07 17:48, G 3 wrote: I made a diagnostic program for the floating point unit. It will test various PowerPC floating point instructions for compatibility with the PowerPC G3 processor. It was tested on a PowerPC G3 and G5 system. The results of the program in qemu-system-ppc were pretty bad. About every instruction tested is not implemented correctly. Here is the download link to the program: http://www.mediafire.com/ file/6j9tqubvk73lkw1/floating_point_test_program.zip Some comments on the code. /* Check if everything is alright */ uint32_t fpscr; asm volatile("mffs f0"); asm volatile("stfd f0, 40(r1)"); asm volatile("lwz %0, 44(r1)" : "=r"(fpscr)); if (fpscr != 0) { printf("Warning: fpscr not equal to zero: 0x%x\n", fpscr); } This is overly complicated and just doesn't compile with recent GCC versions. Which version of GCC had the problem? GCC 5.2 and GCC 3.3 seems to work fine. GCC 4.0 did not work. Could you send me the error message? What about something like: Converter c; asm volatile("mffs %0" : "=f"(c.d)); fpscr = (uint32_t)c.i; This way does work also. /* * The action to take if a test fails * Input one: message string * Input two: actual fpscr value * Input three: expected fpscr value * Input four: actual answer * Input five: expected answer */ void test_failed(const char *message, uint32_t actual_fpscr, uint32_t expected_fpscr, uint64_t actual_answer, uint64_t expected_answer) { printf("%s\n", message); printf("expected answer: 0x%" PRIx64 "\n", expected_answer); printf(" actual answer: 0x%" PRIx64 "\n", actual_fpscr); This is wrong. It should be actual_answer instead of actual_fpscr. That is why all the instructions seems totally wrongly implemented. Thanks for catching this error. Actually this would only effect the "actual answer:" output field. The comparison between expected_answer and actual_answer in each individual test is still valid. Note that compiling with -Wall would give you a warning: | main.c: In function ‘test_failed’: | main.c:146:5: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘uint32_t’ [- Wformat=] | printf(" actual answer: 0x%" PRIx64 "\n", actual_fpscr); | ^ Replacing actual_fpscr with actual_answer should solve this problem.
Re: [Qemu-devel] Floating point unit bugs
On 2017-05-08 18:09, G 3 wrote: > > On May 8, 2017, at 5:54 PM, Aurelien Jarno wrote: > > > On 2017-05-07 17:48, G 3 wrote: > > > I made a diagnostic program for the floating point unit. It will test > > > various PowerPC floating point instructions for compatibility with > > > the > > > PowerPC G3 processor. It was tested on a PowerPC G3 and G5 system. > > > The > > > results of the program in qemu-system-ppc were pretty bad. About > > > every > > > instruction tested is not implemented correctly. > > > > I don't say that qemu-system-ppc is bug free, but this looks suspicious > > that about every instruction is buggy. > > I really hope you don't think I'm blaming anyone. I'm only reporting the > results of the test. > > > Have you tried to run your > > program on a real G3 or G5 system? > > Yes. I made sure it ran on a real G3 and G5 system without problem before > testing it on QEMU. I suspect the Motorola designed G4 processor will not be > compatible. I don't have a working G4 system to verify this unfortunately. > > > > > [ snip ] > > > > > > > > Here is the full test results after running this program in > > > qemu-system-ppc > > > with a Mac OS 10.4 guest: > > > > > > > > > > > > > > > fadd test failed > > > expected answer: 0x3ff4 > > > actual answer: 0x82004024 > > > expected fpscr: 0x82064000 > > > actual fpscr: 0x82004000 > > > > This looks highly suspicious that the actual answer match the expected > > answer. > > You can use this web page to find the decimal value: > http://www6.uniovi.es/~antonio/uned/ieee754/IEEE-754hex64.html > > 0x3ff4 = 1.2002 > 0x82004024 = -4.8529708162167760e-299 > > The expected answer and actual answer are very far from each other. Yes, I made a typo in my comment. I wanted to say that I found very suspicious that the actual answer match the actual fpscr. See my other mail for the reason. -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] Floating point unit bugs
On 2017-05-07 17:48, G 3 wrote: > I made a diagnostic program for the floating point unit. It will test > various PowerPC floating point instructions for compatibility with the > PowerPC G3 processor. It was tested on a PowerPC G3 and G5 system. The > results of the program in qemu-system-ppc were pretty bad. About every > instruction tested is not implemented correctly. > > Here is the download link to the program: > http://www.mediafire.com/file/6j9tqubvk73lkw1/floating_point_test_program.zip Some comments on the code. > > /* Check if everything is alright */ > uint32_t fpscr; > asm volatile("mffs f0"); > asm volatile("stfd f0, 40(r1)"); > asm volatile("lwz %0, 44(r1)" : "=r"(fpscr)); > if (fpscr != 0) { > printf("Warning: fpscr not equal to zero: 0x%x\n", fpscr); > } This is overly complicated and just doesn't compile with recent GCC versions. What about something like: Converter c; asm volatile("mffs %0" : "=f"(c.d)); fpscr = (uint32_t)c.i; > /* > * The action to take if a test fails > * Input one: message string > * Input two: actual fpscr value > * Input three: expected fpscr value > * Input four: actual answer > * Input five: expected answer > */ > void test_failed(const char *message, uint32_t actual_fpscr, uint32_t > expected_fpscr, > uint64_t actual_answer, uint64_t expected_answer) > { > printf("%s\n", message); > printf("expected answer: 0x%" PRIx64 "\n", expected_answer); > printf(" actual answer: 0x%" PRIx64 "\n", actual_fpscr); This is wrong. It should be actual_answer instead of actual_fpscr. That is why all the instructions seems totally wrongly implemented. Note that compiling with -Wall would give you a warning: | main.c: In function ‘test_failed’: | main.c:146:5: warning: format ‘%llx’ expects argument of type ‘long long unsigned int’, but argument 2 has type ‘uint32_t’ [-Wformat=] | printf(" actual answer: 0x%" PRIx64 "\n", actual_fpscr); | ^ So I think the cone needs to be improved a bit before we can conclude anything. Aurelien -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] Floating point unit bugs
On May 8, 2017, at 5:54 PM, Aurelien Jarno wrote: On 2017-05-07 17:48, G 3 wrote: I made a diagnostic program for the floating point unit. It will test various PowerPC floating point instructions for compatibility with the PowerPC G3 processor. It was tested on a PowerPC G3 and G5 system. The results of the program in qemu-system-ppc were pretty bad. About every instruction tested is not implemented correctly. I don't say that qemu-system-ppc is bug free, but this looks suspicious that about every instruction is buggy. I really hope you don't think I'm blaming anyone. I'm only reporting the results of the test. Have you tried to run your program on a real G3 or G5 system? Yes. I made sure it ran on a real G3 and G5 system without problem before testing it on QEMU. I suspect the Motorola designed G4 processor will not be compatible. I don't have a working G4 system to verify this unfortunately. [ snip ] Here is the full test results after running this program in qemu- system-ppc with a Mac OS 10.4 guest: fadd test failed expected answer: 0x3ff4 actual answer: 0x82004024 expected fpscr: 0x82064000 actual fpscr: 0x82004000 This looks highly suspicious that the actual answer match the expected answer. You can use this web page to find the decimal value: http:// www6.uniovi.es/~antonio/uned/ieee754/IEEE-754hex64.html 0x3ff4 = 1.2002 0x82004024 = -4.8529708162167760e-299 The expected answer and actual answer are very far from each other.
Re: [Qemu-devel] Floating point unit bugs
On 2017-05-07 17:48, G 3 wrote: > I made a diagnostic program for the floating point unit. It will test > various PowerPC floating point instructions for compatibility with the > PowerPC G3 processor. It was tested on a PowerPC G3 and G5 system. The > results of the program in qemu-system-ppc were pretty bad. About every > instruction tested is not implemented correctly. I don't say that qemu-system-ppc is bug free, but this looks suspicious that about every instruction is buggy. Have you tried to run your program on a real G3 or G5 system? [ snip ] > > Here is the full test results after running this program in qemu-system-ppc > with a Mac OS 10.4 guest: > > > > > fadd test failed > expected answer: 0x3ff4 > actual answer: 0x82004024 > expected fpscr: 0x82064000 > actual fpscr: 0x82004000 This looks highly suspicious that the actual answer match the expected answer. > actual FPSCR bits set: > bit 17: FPRF - Floating-point greater than or positive > bit 6: XX - Floating-point inexact exception > bit 0: FX - Floating-point exception summary > > expected FPSCR bits set: > bit 17: FPRF - Floating-point greater than or positive > bit 14: FI - Floating-point fraction inexact > bit 13: FR - Floating-point fraction rounded > bit 6: XX - Floating-point inexact exception > bit 0: FX - Floating-point exception summary > > fadds test failed > expected answer: 0x407024d5 > actual answer: 0x82004024 > expected fpscr: 0x82064000 > actual fpscr: 0x82004000 Ditto. > actual FPSCR bits set: > bit 17: FPRF - Floating-point greater than or positive > bit 6: XX - Floating-point inexact exception > bit 0: FX - Floating-point exception summary > > expected FPSCR bits set: > bit 17: FPRF - Floating-point greater than or positive > bit 14: FI - Floating-point fraction inexact > bit 13: FR - Floating-point fraction rounded > bit 6: XX - Floating-point inexact exception > bit 0: FX - Floating-point exception summary > > fsub test passed > fsubs test passed > fmul test failed > expected answer: 0x40365c28f5c28f5c > actual answer: 0x82004024 > expected fpscr: 0x82024000 > actual fpscr: 0x82004000 Ditto. > actual FPSCR bits set: > bit 17: FPRF - Floating-point greater than or positive > bit 6: XX - Floating-point inexact exception > bit 0: FX - Floating-point exception summary > > expected FPSCR bits set: > bit 17: FPRF - Floating-point greater than or positive > bit 14: FI - Floating-point fraction inexact > bit 6: XX - Floating-point inexact exception > bit 0: FX - Floating-point exception summary > > fmuls test failed > expected answer: 0x412135a4a000 > actual answer: 0x82004024 > expected fpscr: 0x82024000 > actual fpscr: 0x82004000 > > actual FPSCR bits set: > bit 17: FPRF - Floating-point greater than or positive > bit 6: XX - Floating-point inexact exception > bit 0: FX - Floating-point exception summary > > expected FPSCR bits set: > bit 17: FPRF - Floating-point greater than or positive > bit 14: FI - Floating-point fraction inexact > bit 6: XX - Floating-point inexact exception > bit 0: FX - Floating-point exception summary > > fdiv test failed > expected answer: 0x40059f38ee13b48b > actual answer: 0x82004024 > expected fpscr: 0x82064000 > actual fpscr: 0x82004000 Ditto. And so on... -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://www.aurel32.net