In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/3ee2f9d8a2d6e90ba8c40dcb14804460a031aab1?hp=e54915d69d47bff3ed6ead9f15d7052ace251ac0>
- Log ----------------------------------------------------------------- commit 3ee2f9d8a2d6e90ba8c40dcb14804460a031aab1 Author: Jarkko Hietaniemi <[email protected]> Date: Mon Oct 6 21:36:04 2014 +0200 The double-double mantissa precision ... it's complicated. M t/op/inc.t commit 1a78f2f425a3e884a0fe2c40ebb1ce5dc7feeeb5 Author: Jarkko Hietaniemi <[email protected]> Date: Mon Oct 6 21:27:28 2014 +0200 AIX/longdouble: switch the default to allow it. Since the only really unfixable part is the inf/nan support. Document the troublesomeness in README.aix. M README.aix M hints/aix.sh commit 6f376839598531b67a3a4384f73266962205ae72 Author: Jarkko Hietaniemi <[email protected]> Date: Mon Oct 6 20:36:29 2014 +0200 Delete obsolete comment fragment. M sv.c commit 68aa61462c42ea6c0ee9bf51b7062f65ef8851ce Author: Jarkko Hietaniemi <[email protected]> Date: Mon Oct 6 20:33:32 2014 +0200 Use the double-double size only if using long double. ... and only for the buffer size, not for the extraction. M sv.c commit de36638a324dc3b5096f7965e67a76dc283861ab Author: Jarkko Hietaniemi <[email protected]> Date: Mon Oct 6 20:02:14 2014 +0200 The leading underscore is optional in Darwin. M t/porting/libperl.t commit 2c93157d2f0bd481c77257e18cfd2782a8385793 Author: Jarkko Hietaniemi <[email protected]> Date: Mon Oct 6 19:55:38 2014 +0200 Bail out if there seem to be no text symbols. Found by Ãvar in an IBM pSeries POWER7 Fedora Linux box. All the text symbols (code) seemed to be 'D' (data). There might be something further to fix regarding the use of 'nm' (or maybe 'ar'?) in this particular box, but this change makes the test more robust against surprising nm results. M t/porting/libperl.t ----------------------------------------------------------------------- Summary of changes: README.aix | 16 ++++++++++++++++ hints/aix.sh | 6 +++--- sv.c | 23 ++++++++++------------- t/op/inc.t | 17 ++++++++++++++++- t/porting/libperl.t | 8 ++++++-- 5 files changed, 51 insertions(+), 19 deletions(-) diff --git a/README.aix b/README.aix index 9a49067..bdacd9d 100644 --- a/README.aix +++ b/README.aix @@ -157,6 +157,22 @@ With the default setting the size is limited to 128MB. The -1 removes this limit. If the "make test" fails please change your /etc/security/limits as stated above. +=head Long doubles + +IBM calls its implementation of long doubles 128-bit, but it is not +the IEEE 128-bit ("quadruple precision") which would give 116 bit of +mantissa (nor it is implemented in hardware), instead it's a special +software implementation called "double-double", which gives 106 bits +of mantissa. + +There seem to be various problems in this long double implementation. +If Configure detects this brokenness, it will disable the long double support. +This can be overriden with explicit C<-Duselongdouble> (or C<-Dusemorebits>, +which enables both long doubles and 64 bit integers). If you decide to +enable long doubles, for most of the broken things Perl has implemented +workarounds, but the handling of the special values infinity and NaN +remains badly broken: for example infinity plus zero results in NaN. + =head2 Recommended Options AIX 5.1/5.2/5.3/6.1 and 7.1 (threaded/32-bit) With the following options you get a threaded Perl version which diff --git a/hints/aix.sh b/hints/aix.sh index 956e806..fce831f 100644 --- a/hints/aix.sh +++ b/hints/aix.sh @@ -584,7 +584,7 @@ fi # The missing math functions affect the POSIX extension math interfaces. case "$uselongdouble" in -define) +'') echo "Checking if your infinity is working with long doubles..." >&4 cat > inf$$.c <<EOF #include <math.h> @@ -598,7 +598,7 @@ EOF $cc -qlongdouble -o inf$$ inf$$.c -lm case `./inf$$` in INF) echo "Your infinity is working correctly with long doubles." >&4 ;; - *) # NaNQ + *) # NaNQ (or anything else than INF) echo " " echo "Your infinity is broken, I suggest disabling long doubles." >&4 rp="Disable long doubles?" @@ -607,7 +607,7 @@ EOF case "$ans" in [Yy]*) echo "Okay, disabling long doubles." >&4 - uselongdouble=undef + uselongdouble="$undef" ccflags=`echo " $ccflags " | sed -e 's/ -qlongdouble / /'` libswanted=`echo " $libswanted " | sed -e 's/ c128/ /'` lddlflags=`echo " $lddlflags " | sed -e 's/ -lc128 / /'` diff --git a/sv.c b/sv.c index a8f2e70..1952500 100644 --- a/sv.c +++ b/sv.c @@ -10805,14 +10805,15 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* vhex, U8* vend) if (vend) *v++ = ((nv) == 0.0) ? 0 : 1; else v++; \ } STMT_END -#ifdef LONGDOUBLE_DOUBLEDOUBLE -# define HEXTRACTSIZE (DOUBLEDOUBLE_MAXBITS/8) + /* HEXTRACTSIZE is the maximum number of xdigits. */ +#if defined(USE_LONG_DOUBLE) && defined(LONGDOUBLE_DOUBLEDOUBLE) +# define HEXTRACTSIZE (DOUBLEDOUBLE_MAXBITS/4) #else -# define HEXTRACTSIZE NVSIZE +# define HEXTRACTSIZE 2 * NVSIZE #endif const U8* nvp = (const U8*)(&nv); - const U8* vmaxend = vhex + 2 * HEXTRACTSIZE + 1; + const U8* vmaxend = vhex + HEXTRACTSIZE; (void)Perl_frexp(PERL_ABS(nv), exponent); if (vend && (vend <= vhex || vend > vmaxend)) Perl_croak(aTHX_ "Hexadecimal float: internal error"); @@ -10976,7 +10977,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* vhex, U8* vend) } # else HEXTRACT_LO_NYBBLE(1); - for (ix = 2; ix < HEXTRACTSIZE; ix++) { + for (ix = 2; ix < NVSIZE; ix++) { HEXTRACT_BYTE(ix); } # endif @@ -10989,7 +10990,7 @@ S_hextract(pTHX_ const NV nv, int* exponent, U8* vhex, U8* vend) /* For double-double the ixmin and ixmax stay at zero, * which is convenient since the HEXTRACTSIZE is tricky * for double-double. */ - ixmin < 0 || ixmax >= HEXTRACTSIZE || + ixmin < 0 || ixmax >= NVSIZE || (vend && v != vend)) Perl_croak(aTHX_ "Hexadecimal float: internal error"); return v; @@ -11959,13 +11960,9 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p * Since each double has their own exponent, the * doubles may float (haha) rather far from each * other, and the number of required bits is much - * larger, up to total of 1028 bits. (NOTE: this - * is not actually implemented properly yet, - * we are using just the first double, see - * S_hextract() for details. But let's prepare - * for the future.) */ - - /* 2 hexdigits for each byte. */ + * larger, up to total of 1028 bits. + * + * Need 2 hexdigits for each byte. */ need += (DOUBLEDOUBLE_MAXBITS/8 + 1) * 2; /* the size for the exponent already added */ #endif diff --git a/t/op/inc.t b/t/op/inc.t index 6003a6c..b494af5 100644 --- a/t/op/inc.t +++ b/t/op/inc.t @@ -1,8 +1,15 @@ #!./perl -w -require './test.pl'; +BEGIN { + chdir 't' if -d 't'; + unshift @INC, '../lib'; + require './test.pl'; +} + use strict; +use Config; + # Tests of post/pre - increment/decrement operators. # Verify that addition/subtraction properly upgrade to doubles. @@ -179,6 +186,12 @@ cmp_ok($a, '==', 2147483647, "postdecrement properly downgrades from double"); cmp_ok($x, '==', 0, "(void) i_postdec"); } +SKIP: { + if ($Config{uselongdouble} && + ($Config{longdblkind} == 6 || $Config{longdoublekind} == 5)) { + skip "the double-double format is weird", 1; + } + # I'm sure that there's an IBM format with a 48 bit mantissa # IEEE doubles have a 53 bit mantissa # 80 bit long doubles have a 64 bit mantissa @@ -245,6 +258,8 @@ EOC ok($found, "found a NV value which overflows the mantissa"); +} # SKIP + # these will segfault if they fail sub PVBM () { 'foo' } diff --git a/t/porting/libperl.t b/t/porting/libperl.t index 6b441e5..550a97b 100644 --- a/t/porting/libperl.t +++ b/t/porting/libperl.t @@ -252,7 +252,7 @@ sub nm_parse_darwin { $symbols->{data}{const}{$symbol}{$symbols->{o}}++; } elsif (/^\(__TEXT,__text\) (?:non-)?external _(\w+)$/) { $symbols->{text}{$1}{$symbols->{o}}++; - } elsif (/^\(__DATA,__\w*?(const|data|bss|common)\w*\) (?:non-)?external _(\w+)(\.\w+)?$/) { + } elsif (/^\(__DATA,__\w*?(const|data|bss|common)\w*\) (?:non-)?external _?(\w+)(\.\w+)?$/) { my ($dtype, $symbol, $suffix) = ($1, $2, $3); # Ignore function-local constants like # _Perl_pp_gmtime.dayname @@ -303,9 +303,13 @@ while (<$nm_fh>) { # use Data::Dumper; print Dumper(\%symbols); -if (keys %symbols == 0) { +# Something went awfully wrong. Wrong nm? Wrong options? +unless (keys %symbols) { skip_all "no symbols\n"; } +unless (exists $symbols{text}) { + skip_all "no text symbols\n"; +} # These should always be true for everyone. -- Perl5 Master Repository
