Created attachment 209239 [details] Log of compile and output of assembly and check of fp128 data. I tested this on both r351523 ppc64 and riscv r350568 as well as the recent jenkins r354823 where valid and reasonable fp128 little endian data is mis-reported via printf thus : /************************************************* * The Open Group Base Specifications Issue 6 * IEEE Std 1003.1, 2004 Edition *************************************************/ #define _XOPEN_SOURCE 600 #include <ctype.h> #include <errno.h> #include <inttypes.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> #include <sys/utsname.h> int main ( int argc, char *argv[] ) { /* note hex representation of pi is * 0x4000 0x921f 0xb544 0x42d1 0x8469 0x898c 0xc517 0x01b8 * IEEE754-2008 binary64 hex representation of pi is * 40 09 21 fb 54 44 2d 18 */ int j; long double pi = 3.14159265358979323846264338327950288419716939937510L; struct utsname uname_data; setlocale( LC_MESSAGES, "C" ); if ( uname( &uname_data ) < 0 ) { fprintf ( stderr, "WARNING : Could not attain system uname data.\n" ); perror ( "uname" ); } else { printf ( "-------------------------------" ); printf ( "------------------------------\n" ); printf ( " system name = %s\n", uname_data.sysname ); printf ( " node name = %s\n", uname_data.nodename ); printf ( " release = %s\n", uname_data.release ); printf ( " version = %s\n", uname_data.version ); printf ( " machine = %s\n", uname_data.machine ); printf ( "-------------------------------" ); printf ( "------------------------------" ); } printf ("\n"); uint8_t x86_fp80[16] = { 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; printf("x86_fp80[16]\n"); printf(" 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9,\n"); printf(" 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n"); printf("out "); for ( j=0; j<16; j++ ) { printf("0x%02x ", ((uint8_t *)&x86_fp80)[j] ); } printf("\n"); printf(" x86_fp80 may be %38.34Le\n", *(long double*)&x86_fp80); printf(" x86_fp80 or be %18.14g\n", *(double*)&x86_fp80); printf("-------------------------------------------------\n"); uint8_t pi_fp64le[16] = { 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; printf("pi_fp64le[16]\n"); printf(" 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40,\n"); printf(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n"); printf("out "); for ( j=0; j<16; j++ ) { printf("0x%02x ", ((uint8_t *)&pi_fp64le)[j] ); } printf("\n"); printf(" pi_fp64le may be %38.34Le\n", *(long double*)&pi_fp64le); printf(" pi_fp64le or be %18.14g\n", *(double*)&pi_fp64le); printf("-------------------------------------------------\n"); uint8_t pi_fp64be[16] = { 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; printf("pi_fp64be[16]\n"); printf(" 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18,\n"); printf(" 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n"); printf("out "); for ( j=0; j<16; j++ ) { printf("0x%02x ", ((uint8_t *)&pi_fp64be)[j] ); } printf("\n"); printf(" pi_fp64be may be %38.34Le\n", *(long double*)&pi_fp64be); printf(" pi_fp64be or be %18.14g\n", *(double*)&pi_fp64be); printf("-------------------------------------------------\n"); uint8_t pi_fp128le[16] = { 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, 0x84, 0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x40 }; printf("pi_fp128le[16]\n"); printf(" 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, 0x84,\n"); printf(" 0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x40\n"); printf("out "); for ( j=0; j<16; j++ ) { printf("0x%02x ", ((uint8_t *)&pi_fp128le)[j] ); } printf("\n"); printf(" pi_fp128le may be %38.34Le\n", *(long double*)&pi_fp128le); printf(" pi_fp128le or be %18.14g\n", *(double*)&pi_fp128le); printf("-------------------------------------------------\n"); uint8_t pi_fp128be[16] = { 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, 0xd1, 0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0xb8 }; printf("pi_fp128be[16]\n"); printf(" 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, 0xd1,\n"); printf(" 0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0xb8\n"); printf("out "); for ( j=0; j<16; j++ ) { printf("0x%02x ", ((uint8_t *)&pi_fp128be)[j] ); } printf("\n"); printf(" pi_fp128be may be %38.34Le\n", *(long double*)&pi_fp128be); printf(" pi_fp128be or be %18.14g\n", *(double*)&pi_fp128be); printf("-------------------------------------------------\n"); for ( j=0; j<sizeof(long double); j++ ) printf("%02x ", ((unsigned char *)&pi)[j] ); printf("\n" ); printf("pi may be %38.34Le\n", pi); return (EXIT_SUCCESS); } The output from the above on a Solaris 10 Fujitsu sparcv9 server is correctly : beta $ beta $ /opt/bw/gcc9/bin/gcc -std=iso9899:1999 -pedantic -fno-builtin -g -m64 -o hex_hack hex_hack.c beta $ beta $ ./hex_hack ------------------------------------------------------------- system name = SunOS node name = beta release = 5.10 version = Generic_150400-65 machine = sun4u ------------------------------------------------------------- x86_fp80[16] 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x35 0xc2 0x68 0x21 0xa2 0xda 0x0f 0xc9 0x00 0x40 0x00 0x00 0x00 0x00 0x00 0x00 x86_fp80 may be 1.4079991028348808823621394844517895e-789 x86_fp80 or be 9.839389446594e-50 ------------------------------------------------- pi_fp64le[16] 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x18 0x2d 0x44 0x54 0xfb 0x21 0x09 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64le may be 2.5291464540223296389757969198439224e-3069 pi_fp64le or be 3.2073756306764e-192 ------------------------------------------------- pi_fp64be[16] 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x40 0x09 0x21 0xfb 0x54 0x44 0x2d 0x18 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64be may be 1.1599270182075852062553167343139648e+03 pi_fp64be or be 3.1415926535898 ------------------------------------------------- pi_fp128le[16] 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, 0x84, 0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x40 out 0xb8 0x01 0x17 0xc5 0x8c 0x89 0x69 0x84 0xd1 0x42 0x44 0xb5 0x1f 0x92 0x00 0x40 pi_fp128le may be -1.3526724668465106417844259659978911e-616 pi_fp128le or be -6.2789244204581e-39 ------------------------------------------------- pi_fp128be[16] 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, 0xd1, 0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0xb8 out 0x40 0x00 0x92 0x1f 0xb5 0x44 0x42 0xd1 0x84 0x69 0x89 0x8c 0xc5 0x17 0x01 0xb8 pi_fp128be may be 3.1415926535897932384626433832795028e+00 pi_fp128be or be 2.0713495408494 ------------------------------------------------- 40 00 92 1f b5 44 42 d1 84 69 89 8c c5 17 01 b8 pi may be 3.1415926535897932384626433832795028e+00 beta $ Whereas the AMD Opteron based FreeBSD 12.1 release will report the best intel fp80 format data thus : vesta$ vesta$ ./hex_hack ------------------------------------------------------------- system name = FreeBSD node name = vesta release = 12.1-RELEASE version = FreeBSD 12.1-RELEASE r354233 GENERIC machine = amd64 ------------------------------------------------------------- x86_fp80[16] 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x35 0xc2 0x68 0x21 0xa2 0xda 0x0f 0xc9 0x00 0x40 0x00 0x00 0x00 0x00 0x00 0x00 x86_fp80 may be 3.1415926535897932385128089594061862e+00 x86_fp80 or be -8.8796093704934e+43 ------------------------------------------------- pi_fp64le[16] 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x18 0x2d 0x44 0x54 0xfb 0x21 0x09 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64le may be 1.6819886204449109911174915236564559e-4932 pi_fp64le or be 3.1415926535898 ------------------------------------------------- pi_fp64be[16] 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x40 0x09 0x21 0xfb 0x54 0x44 0x2d 0x18 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64be may be 6.3503887240691950845592893794047029e-4933 pi_fp64be or be 3.2073756306764e-192 ------------------------------------------------- pi_fp128le[16] 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, 0x84, 0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x40 out 0xb8 0x01 0x17 0xc5 0x8c 0x89 0x69 0x84 0xd1 0x42 0x44 0xb5 0x1f 0x92 0x00 0x40 pi_fp128le may be 2.2823123577349716480961329732730512e+217 pi_fp128le or be -2.0963761001907e-287 ------------------------------------------------- pi_fp128be[16] 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, 0xd1, 0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0xb8 out 0x40 0x00 0x92 0x1f 0xb5 0x44 0x42 0xd1 0x84 0x69 0x89 0x8c 0xc5 0x17 0x01 0xb8 pi_fp128be may be 7.2660402568558392281485015532366322e+3199 pi_fp128be or be -2.7726117564375e+83 ------------------------------------------------- 35 c2 68 21 a2 da 0f c9 00 40 00 00 00 00 00 00 pi may be 3.1415926535897932385128089594061862e+00 vesta$ The recent ( and older r350568 ) r354823 reports the very wrong data in spite of having flawless perfect little endian fp128 in memory representation : # # uname -apKU FreeBSD 13.0-CURRENT FreeBSD 13.0-CURRENT #0 r354823: Mon Nov 18 19:49:20 UTC 2019 jenkins@FreeBSD-head-riscv64-build.jail.ci.FreeBSD.org:/tmp/obj/workspace/src/riscv.riscv64/sys/RISCVTEST riscv riscv64 1300058 1300058 # # # ./hex_hack.rv64imafdc ------------------------------------------------------------- system name = FreeBSD node name = release = 13.0-CURRENT version = FreeBSD 13.0-CURRENT #0 r354823: Mon Nov 18 19:49:20 UTC 2019 jenkins@FreeBSD-head-riscv64-build.jail.ci.FreeBSD.org:/tmp/obj/workspace/src/riscv.riscv64/sys/RISCVTEST machine = riscv ------------------------------------------------------------- x86_fp80[16] 0x35, 0xc2, 0x68, 0x21, 0xa2, 0xda, 0x0f, 0xc9, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x35 0xc2 0x68 0x21 0xa2 0xda 0x0f 0xc9 0x00 0x40 0x00 0x00 0x00 0x00 0x00 0x00 x86_fp80 may be 4.5565357090895492502716873808281576e-4952 x86_fp80 or be -8.8796093704934e+43 ------------------------------------------------- pi_fp64le[16] 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x18 0x2d 0x44 0x54 0xfb 0x21 0x09 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64le may be 1.2844077354038319064254933956786494e-4937 pi_fp64le or be 3.1415926535898 ------------------------------------------------- pi_fp64be[16] 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 out 0x40 0x09 0x21 0xfb 0x54 0x44 0x2d 0x18 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 pi_fp64be may be 1.2844077354038319066067654139395456e-4937 pi_fp64be or be 3.2073756306764e-192 ------------------------------------------------- pi_fp128le[16] 0xb8, 0x01, 0x17, 0xc5, 0x8c, 0x89, 0x69, 0x84, 0xd1, 0x42, 0x44, 0xb5, 0x1f, 0x92, 0x00, 0x40 out 0xb8 0x01 0x17 0xc5 0x8c 0x89 0x69 0x84 0xd1 0x42 0x44 0xb5 0x1f 0x92 0x00 0x40 pi_fp128le may be 2.0000076405016834831430856216761921e+00 pi_fp128le or be -2.0963761001907e-287 ------------------------------------------------- pi_fp128be[16] 0x40, 0x00, 0x92, 0x1f, 0xb5, 0x44, 0x42, 0xd1, 0x84, 0x69, 0x89, 0x8c, 0xc5, 0x17, 0x01, 0xb8 out 0x40 0x00 0x92 0x1f 0xb5 0x44 0x42 0xd1 0x84 0x69 0x89 0x8c 0xc5 0x17 0x01 0xb8 pi_fp128be may be -1.2377431474242674717718477250561708e-616 pi_fp128be or be -2.7726117564375e+83 ------------------------------------------------- b8 01 17 c5 8c 89 69 84 d1 42 44 b5 1f 92 00 40 pi may be 2.0000076405016834831430856216761921e+00 # I checked the assembly and the static data given to the assembler is bit for bit perfect : rv64g$ cat hex_hack.s .file "hex_hack.c" .option nopic .text .align 1 .type uname, @function uname: addi sp,sp,-32 sd ra,24(sp) sd s0,16(sp) addi s0,sp,32 sd a0,-24(s0) ld a1,-24(s0) li a0,256 call __xuname mv a5,a0 mv a0,a5 ld ra,24(sp) ld s0,16(sp) addi sp,sp,32 jr ra .size uname, .-uname .section .rodata .align 3 .LC6: .string "C" .align 3 . . . .LC46: .string "pi may be %38.34Le\n" .align 3 . . . main: addi sp,sp,-1424 sd ra,1416(sp) sd s0,1408(sp) addi s0,sp,1424 mv a5,a0 sd a1,-1424(s0) sw a5,-1412(s0) lui a5,%hi(.LC5) ld a4,%lo(.LC5)(a5) sd a4,-48(s0) ld a5,%lo(.LC5+8)(a5) sd a5,-40(s0) lui a5,%hi(.LC6) addi a1,a5,%lo(.LC6) li a0,6 call setlocale addi a5,s0,-1328 mv a0,a5 call uname . . . . .L16: lw a5,-20(s0) mv a4,a5 li a5,15 bleu a4,a5,.L17 lui a5,%hi(.LC17) addi a0,a5,%lo(.LC17) call printf ld a5,-48(s0) ld a6,-40(s0) mv a2,a5 mv a3,a6 lui a5,%hi(.LC46) addi a0,a5,%lo(.LC46) call printf li a5,0 mv a0,a5 ld ra,1416(sp) ld s0,1408(sp) addi sp,sp,1424 jr ra .size main, .-main .section .rodata .align 4 .LC5: .word 3306619320 .word 2221509004 .word 3041149649 .word 1073779231 .ident "GCC: (GNU) 8.2.0" rv64g$ The static data at LC5 is correct thus : rv64g$ echo '16o 1073779231p 3041149649p 2221509004p 3306619320pq' | dc 4000921F B54442D1 8469898C C51701B8 rv64g$ However the output from printf("pi may be %38.34Le\n", pi) is clearly wrong. -- Dennis Clarke RISC-V/SPARC/PPC/ARM/CISC UNIX and Linux spoken GreyBeard and suspenders optional
Modify bug arch to riscv.
Created attachment 209240 [details] Assemble , compile and link and check results.
Thank you for the report Dennis Could you: - Summarise the specific expected vs actual output - Clarify/confirm whether or not this is a regression (post base r351523 ppc64 / / base r350568 riscv / base r354823 jenkins) and - If a regression, the latest revision that *didn't* exhibit the issue. Bisection here would be perfect, if possible.
(In reply to Kubilay Kocak from comment #3) The output should be the valid IEEE754-2008 floating point representation for pi exactly the same as the Solaris 10 sparcv9 server does : ( 1 ) expected output should be in the last lines : b8 01 17 c5 8c 89 69 84 d1 42 44 b5 1f 92 00 40 pi may be 3.1415926535897932384626433832795028e+00 That would be precisely correct for a little endian RISC-V architecture. ( 2 ) actual output is very correct in memory and very wrong printf behavior : b8 01 17 c5 8c 89 69 84 d1 42 44 b5 1f 92 00 40 pi may be 2.0000076405016834831430856216761921e+00 # So I don't think that pi is that close to 2.00000764... :) The other question is have I ever seen this work ? The answer is no. Sadly I have never seen this work correctly. The output here suggests that the printf() routine correctly handles the static format string seen in the assembly listing at LC46 in that we do get the correct number of ascii digits in the correct places however the in memory little endian fp128 data is not handled well. The text [1]"Handbook of Floating-Point Arithmetic", 2nd Ed, pg48, by Muller, J.-M., Brunie, N., de Dinechin, F., Jeannerod, C.-P., Joldes, M., Lefèvre, V., Melquiond, G., Revol, N., Torres, S. states that the 128 bit floating point format should have a single sign bit, a set of 15 exponent bits and then a mantissa or significand of 112 bits wherein there is an implied leading "1" bit for an effective 113 bit significand. The IEEE 754-1985 standard did not define this format whereas the [2]IEEE 754-2008 standard does. This is well implemented in Solaris and OpenSolaris as well as on IBM Power9 systems running Red Hat Enterprise Linux. I have single stepped through the relevant lines of the code on an IBM Power system and I think the issue is with /lib/libc/stdio/vfprintf.c where the in memory data is handled wrongly. I have a theory on why we are seeing a value near 2.0 but have to work on that yet. [1] https://www.springer.com/gp/book/9783319765259 [2] IEEE Computer Society. IEEE Standard for Floating-Point Arithmetic. IEEE Standard 754-2008, August 2008. also ISBN: 978-0-7381-5752-8 https://ieeexplore.ieee.org/document/4610935
The output from the Solaris 10 sparcv9 server is clearly to be big endian however for claity I simply want to point out that the RISC-V architecture is little endian and that the in memory data is precisely correct. Regardless we should never see a value of pi as 2.0000...
Merely a follow up here to indicate this problem has been around since at least r350568 : root@callisto:/home/dclarke/foo # uname -apKU FreeBSD callisto 13.0-CURRENT FreeBSD 13.0-CURRENT r350568 QEMU riscv riscv64 1300038 1300038 root@callisto:/home/dclarke/foo # root@callisto:/home/dclarke/foo # cat pi.c /************************************************* * The Open Group Base Specifications Issue 6 * IEEE Std 1003.1, 2004 Edition *************************************************/ #define _XOPEN_SOURCE 600 #include <stdio.h> #include <stdlib.h> #include <math.h> int main ( int argc, char *argv[]) { long double pi128 = 3.1415926535897932384626433832795028841971693993751L; double pi64 = M_PI; printf (" the sizeof(pi128) is %i\n", sizeof(pi128) ); printf (" the sizeof(pi64) is %i\n", sizeof(pi64) ); printf ("pi128 may be %44.38Lg\n", pi128 ); printf ("pi64 may be %18.16g\n", pi64 ); return ( EXIT_SUCCESS ); } root@callisto:/home/dclarke/foo # root@callisto:/home/dclarke/foo # cat pi.s .file "pi.c" .option nopic .text .section .rodata .align 3 .LC2: .string " the sizeof(pi128) is %i\n" .align 3 .LC3: .string " the sizeof(pi64) is %i\n" .align 3 .LC4: .string "pi128 may be %44.38Lg\n" .align 3 .LC5: .string "pi64 may be %44.38Lg\n" .text .align 1 .globl main .type main, @function main: addi sp,sp,-64 sd ra,56(sp) sd s0,48(sp) addi s0,sp,64 mv a5,a0 sd a1,-64(s0) sw a5,-52(s0) lui a5,%hi(.LC0) ld a4,%lo(.LC0)(a5) sd a4,-32(s0) ld a5,%lo(.LC0+8)(a5) sd a5,-24(s0) lui a5,%hi(.LC1) fld fa5,%lo(.LC1)(a5) fsd fa5,-40(s0) li a1,16 lui a5,%hi(.LC2) addi a0,a5,%lo(.LC2) call printf li a1,8 lui a5,%hi(.LC3) addi a0,a5,%lo(.LC3) call printf ld a2,-32(s0) ld a3,-24(s0) lui a5,%hi(.LC4) addi a0,a5,%lo(.LC4) call printf ld a1,-40(s0) lui a5,%hi(.LC5) addi a0,a5,%lo(.LC5) call printf li a5,0 mv a0,a5 ld ra,56(sp) ld s0,48(sp) addi sp,sp,64 jr ra .size main, .-main .section .rodata .align 4 .LC0: .word 3306619320 .word 2221509004 .word 3041149649 .word 1073779231 .align 3 .LC1: .word 1413754136 .word 1074340347 .ident "GCC: (GNU) 8.2.0" root@callisto:/home/dclarke/foo # root@callisto:/home/dclarke/foo # root@callisto:/home/dclarke/foo # ./pi the sizeof(pi128) is 16 the sizeof(pi64) is 8 pi128 may be 2.0000076293945362811600603241536472604 pi64 may be 3.141592653589793 root@callisto:/home/dclarke/foo # root@callisto:/home/dclarke/foo # echo "16o 1074340347p 1413754136pq" | dc 400921FB 54442D18 root@callisto:/home/dclarke/foo # echo "16o 1073779231p 3041149649p 2221509004p 3306619320pq" | dc 4000921F B54442D1 8469898C C51701B8 root@callisto:/home/dclarke/foo # So that is perfect in memory and wrong in output. -- Dennis Clarke RISC-V/SPARC/PPC/ARM/CISC UNIX and Linux spoken GreyBeard and suspenders optional
Yep, we have a problem in FreeBSD 13.0-CURRENT r355009 perhaps in _ldtoa.c still and I think maybe the real issue is with head/lib/libc/gdtoa/machdep_ldisQ.c where we see /* * Machine-dependent glue to integrate David Gay's gdtoa * package into libc for architectures where a long double * uses quad precision, such as sparc64. */ Well bingo ... other than the endianess we have the same data in memory and confusion in the printf output. So still digging. -- Dennis Clarke RISC-V/SPARC/PPC/ARM/CISC UNIX and Linux spoken GreyBeard and suspenders optional
Hi Dennis, Thanks for the detailed report. I was finally able to find the source of the issue: GCC used to generate 64-bit long doubles and the workaround for that was still enabled. I've posted a patch addressing the issue here: https://reviews.freebsd.org/D25420 The test program gives the expected output for me, but if you'd like to verify the fix at well it would be helpful.
A commit references this bug: Author: mhorne Date: Mon Jun 29 19:30:35 UTC 2020 New revision: 362788 URL: https://svnweb.freebsd.org/changeset/base/362788 Log: Fix printf(3) output of long doubles on RISC-V When the RISC-V port was initially committed to FreeBSD, GCC would generate 64-bit long doubles, and the definitions in _fpmath.h reflected that. This was changed to 128-bit in GCC later that year [1], but the definitions were never updated, despite the documented workaround. This causes printf(3) and friends to interpret only the low 64-bits of a long double in ldtoa, thereby printing incorrect values. Update the definitions now that both clang and GCC generate 128-bit long doubles. [1] https://github.com/riscv/riscv-gcc/commit/54b21fc5ae83cefec44bc2caed4a8c664c274ba0 PR: 242067 Reported by: Dennis Clarke <dclarke@blastwave.org> MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D25420 Changes: head/lib/libc/riscv/_fpmath.h
A commit references this bug: Author: mhorne Date: Mon Jul 6 15:00:29 UTC 2020 New revision: 362964 URL: https://svnweb.freebsd.org/changeset/base/362964 Log: MFC r362788: Fix printf(3) output of long doubles on RISC-V PR: 242067 Changes: stable/12/lib/libc/riscv/_fpmath.h