In metaconfig.git, the branch master has been updated <http://perl5.git.perl.org/metaconfig.git/commitdiff/b0155347fba5ea289b824edceea23d4508c66b1b?hp=fcb1c4606368749ccc1d7e21dcc1a86d61a56f66>
- Log ----------------------------------------------------------------- commit b0155347fba5ea289b824edceea23d4508c66b1b Author: Aaron Crane <a...@cpan.org> Date: Thu Apr 21 15:11:05 2016 +0100 [UTIL] New simplifydiff tool Pipe a diff into it, and it removes any diff hunk in which every insertion was deleted by some other part of the diff, and every deletion was inserted by some other part. A bin/simplifydiff commit 9c52d4117799c8de73f4871a148d3bb88fe5214d Author: Aaron Crane <a...@cpan.org> Date: Thu Apr 21 15:06:25 2016 +0100 Various updates to float-format probes Backported from the following: commit b5897239a0c3c2f5ec699690086b30e7db4305d4 Author: Jarkko Hietaniemi <j...@iki.fi> Date: Tue Dec 8 08:40:38 2015 -0500 Configure: cannot trust the bytes after the 80-bit fp They can be zero, they can be garbage. commit 3118d7d684b56cbeb702af874f4326683c45f045 Author: Jarkko Hietaniemi <j...@iki.fi> Date: Tue Dec 8 08:48:40 2015 -0500 Configure: mixed-endian double-doubles The ppc64el is the first seen little-endian double-double (and also the first little-endian ppc), but it turns out its little-endianness is mixed: the doubles are still in big-endian order. Configure was expecting wrongly a fully byte-reversed double-double. Therefore extend the long double format detection to cover all the (double-double) permutations, though the formats of five and eight are rather unlikely (based on current platforms using double-double). commit 74c6ce8743ba719b8416ce00933e19104484b949 Author: Jarkko Hietaniemi <j...@iki.fi> Date: Thu Dec 10 18:59:53 2015 -0500 Configure: infnan for mixed-endian double-double commit 157a0ac7a2e2f56bd291b87c343712def4a1acfb Author: Jarkko Hietaniemi <j...@iki.fi> Date: Wed Dec 16 21:57:31 2015 -0500 Configure: notes on the m68881 extended precision format M U/modified/d_longdbl.U M U/perl/infnan.U M U/perl/mantbits.U ----------------------------------------------------------------------- Summary of changes: U/modified/d_longdbl.U | 45 +++++++++++++++++++++++++++------ U/perl/infnan.U | 12 +++++++-- U/perl/mantbits.U | 2 +- bin/simplifydiff | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 11 deletions(-) create mode 100755 bin/simplifydiff diff --git a/U/modified/d_longdbl.U b/U/modified/d_longdbl.U index 3e9fbe0..4d1a1a5 100644 --- a/U/modified/d_longdbl.U +++ b/U/modified/d_longdbl.U @@ -174,17 +174,26 @@ int main() { } #endif /* For alignment 32-bit platforms have the 80 bits in 12 bytes, - * while 64-bits platforms have it in 16 bytes. */ + * while 64-bits platforms have it in 16 bytes. The trailing bytes + * cannot be trusted. */ #if LDBL_MANT_DIG == 64 && (LONGDBLSIZE == 16 || LONGDBLSIZE == 12) - if (b[0] == 0xCD && b[9] == 0xBF && b[10] == 0x00) { + if (b[0] == 0xCD && b[9] == 0xBF) { /* x86 80-bit little-endian, sizeof 12 (ILP32, Solaris x86) * or 16 (LP64, Linux and OS X), 4 or 6 bytes of padding. * Also known as "extended precision". */ printf("3\n"); exit(0); } - if (b[0] == 0xBF && b[9] == 0xCD && b[10] == 0x00) { - /* is there ever big-endian 80-bit, really? */ + if (b[0] == 0xBF && b[9] == 0xCD) { + /* Is there ever big-endian 80-bit, really? + * + * The Motorola 68881 had another "extended precision" format: + * sign:1 exp:15 zero:16 integer:1 mantissa:63 + * for total of 96 bits of bytes. The zero bits were unused. + * See "M68000 FAMILY PROGRAMMERâS REFERENCE MANUAL" for more details. + * If it ever becomes relevant, this format should be allocated + * a new doublekind code since it's quite different from the Intel x87. + */ printf("4\n"); exit(0); } @@ -193,17 +202,35 @@ int main() { /* software "double double", the 106 is 53+53. * but irix thinks it is 107. */ if (b[0] == 0x9A && b[7] == 0x3C && b[8] == 0x9A && b[15] == 0xBF) { - /* double double 128-bit little-endian, + /* double double 128-bit fully little-endian, + * little-endian doubles in little-endian order, * 9a 99 99 99 99 99 59 3c 9a 99 99 99 99 99 b9 bf */ printf("5\n"); exit(0); } if (b[0] == 0xBF && b[7] == 0x9A && b[8] == 0x3C && b[15] == 0x9A) { - /* double double 128-bit big-endian, e.g. PPC/Power and MIPS: + /* double double 128-bit fully big-endian, + * big-endian doubles in big-endian order, + * e.g. PPC/Power and MIPS: * bf b9 99 99 99 99 99 9a 3c 59 99 99 99 99 99 9a */ printf("6\n"); exit(0); } + if (b[0] == 0x9A && b[7] == 0xBF && b[8] == 0x9A && b[15] == 0x3C) { + /* double double 128-bit mixed endian. + * little-endian doubles in big-endian order, + * e.g. ppc64el, + * 9a 99 99 99 99 99 b9 bf 9a 99 99 99 99 99 59 3c */ + printf("7\n"); + exit(0); + } + if (b[0] == 0x3C && b[7] == 0x9A && b[8] == 0xBF && b[15] == 0x9A) { + /* double double 128-bit mixed endian, + * big-endian doubles in little-endian order, + * 3c 59 99 99 99 99 99 9a bf b9 99 99 99 99 99 9a */ + printf("8\n"); + exit(0); + } #endif printf("-1\n"); /* unknown */ exit(0); @@ -224,8 +251,10 @@ case "$longdblkind" in 2) echo "You have IEEE 754 128-bit big endian long doubles." >&4 ;; 3) echo "You have x86 80-bit little endian long doubles." >& 4 ;; 4) echo "You have x86 80-bit big endian long doubles." >& 4 ;; -5) echo "You have 128-bit little-endian double-double long doubles." >& 4 ;; -6) echo "You have 128-bit big-endian double-double long doubles." >& 4 ;; +5) echo "You have 128-bit fully little-endian double-double long doubles (64-bit LEs in LE)." >& 4 ;; +6) echo "You have 128-bit fully big-endian double-double long doubles (64-bit BEs in BE)." >& 4 ;; +7) echo "You have 128-bit mixed double-double long doubles (64-bit LEs in BE)." >& 4 ;; +8) echo "You have 128-bit mixed double-double long doubles (64-bit BEs in LE)." >& 4 ;; *) echo "Cannot figure out your long double." >&4 ;; esac $rm_try diff --git a/U/perl/infnan.U b/U/perl/infnan.U index e253b45..de4026e 100644 --- a/U/perl/infnan.U +++ b/U/perl/infnan.U @@ -195,14 +195,22 @@ else ;; esac ;; - 5) # 128-bit LE "double double" + 5) # 128-bit LE-LE "double double" longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f' longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f' ;; - 6) # 128-bit BE "double double" + 6) # 128-bit BE-BE "double double" longdblinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' longdblnanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' ;; + 7) # 128-bit LE-BE "double double" + longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + ;; + 8) # 128-bit BE-LE "double double" + longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + ;; *) # No idea. longdblinfbytes=$undef longdblnanbytes=$undef diff --git a/U/perl/mantbits.U b/U/perl/mantbits.U index e937e05..ef4949f 100644 --- a/U/perl/mantbits.U +++ b/U/perl/mantbits.U @@ -103,7 +103,7 @@ $cat >try.c <<EOP * and the top bit must have been one since 387, zero is plain invalid. * For normal fp values, the LDBL_MANT_DIG is fine, though. */ # define BITS LDBL_MANT_DIG -# elif ($longdblkind == 5 || $longdblkind == 6) /* double double */ +# elif ($longdblkind == 5 || $longdblkind == 6 || $longdblkind == 7 || $longdblkind == 8) /* double double */ /* LDBL_MANT_DIG of 106 (twice 53) would be logical, but for some * reason e.g. Irix thinks 107. But in any case, we want only * the number of real bits, the implicit bits are of no interest. */ diff --git a/bin/simplifydiff b/bin/simplifydiff new file mode 100755 index 0000000..aba9e1d --- /dev/null +++ b/bin/simplifydiff @@ -0,0 +1,68 @@ +#! /usr/bin/env perl + +use v5.16; +use warnings; + +# Take a unified diff (perhaps from "git diff" or similar) on stdin, and +# delete hunks where (a) every "ins" line in the hunk also appears in a +# "del" line somewhere in the diff, and (b) every "del" line in the hunk +# also appears in an "ins" line somewhere in the diff. + +die "Usage: diff ... | nontrivdiff\n" if @ARGV; + +sub break_before (&@) { + my $predicate = shift; + my (@curr, @groups); + for (@_) { + push @groups, [splice @curr] + if @curr && $predicate->($_); + push @curr, $_; + } + push @groups, \@curr if @curr; + return @groups; +} + +my @all_lines = <>; + +my @head; +push @head, shift @all_lines + while @all_lines && $all_lines[0] =~ /^diff |^index |^--- |^\+\+\+ /; + +die "Can't handle multi-file diffs\n" + if grep /^--- |^\+\+\+ /, @all_lines; + +my (%ins, %del); +for (@all_lines) { + next if /^\@\@ |^ /; + my ($c, $line) = /([-+])(.*)/s or die "can't parse: $_"; + $line =~ s/[ \t]+/ /g; + my $h = $c eq '-' ? \%del : \%ins; + $h->{$line}++; +} + +my @out; +for my $hunk (break_before { /^\@\@ / } @all_lines) { + push @out, @$hunk if any_changes_missing($hunk); +} + +print @head, @out if @out; + +sub any_changes_missing { + my ($hunk) = @_; + + my %lins = %ins; + my %ldel = %del; + + for (@$hunk) { + next if /^\@\@ |^ /; + my ($c, $line) = /([-+])(.*)/s or die "can't parse: $_"; + $line =~ s/[ \t]+/ /g; + my $h = $c eq '-' ? \%lins : \%ldel; + return 1 if !$h->{$line}; + $h->{$line}--; + } + + %ins = %lins; + %del = %ldel; + return 0; +} -- perl5 metaconfig repository