Skip to content

Commit

Permalink
pre-calculate FLOATTYPE
Browse files Browse the repository at this point in the history
FLOATTYPE is cpu dependent for long double. Better do that
in a config step, not at run-time.
Improve __float128 support.
  • Loading branch information
Reini Urban committed Sep 8, 2012
1 parent 60b281e commit 1cb93a8
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 46 deletions.
53 changes: 39 additions & 14 deletions config/auto/format.pm
Expand Up @@ -61,51 +61,76 @@ sub _set_intvalfmt {

sub _set_floatvalfmt_nvsize {
my $conf = shift;
my ( $nv, $floatsize, $doublesize, $ldsize ) =
$conf->data->get(qw(nv floatsize doublesize hugefloatvalsize));
my ( $nvformat, $nvsize );
my ( $nv, $floatsize, $doublesize, $ldsize, $cpuarch ) =
$conf->data->get(qw(nv floatsize doublesize hugefloatvalsize cpuarch));
my ( $nvformat, $nvsize, $floattype );
$nvsize = $floatsize;
if ( $nv eq "double" ) {
$nvsize = $doublesize;
$nvformat = "%.15g";
$floattype = 'FLOATTYPE_8';
}
elsif ( $nv eq "long double" ) {

# long double may be 64 or 80 bits or even quadmath.
# 64 or 80 bits, 12 or 16 bytes
$nvsize = $ldsize;
my $spri = $conf->data->get('sPRIgldbl_provisional');
if ( defined $spri ) {
# TT #308 same values as in imcc
if ($nvsize == 8) {
$floattype = 'FLOATTYPE_8';
$nvformat = "%.16" . $spri;
}
elsif ($nvsize == 12) {
$floattype = 'FLOATTYPE_10';
$nvformat = "%.16Lg"; # i386 only
}
elsif ($nvsize == 16) {
# only on a sparc64/s390 or __float128. intel cheats
$nvformat = $nv eq '__float128'
? "%Qe" # libquadmath printf hook support (linux only).
# TODO probe for it.
: "%.16Lg"; # intel, ppc, mips, aix
$nvformat = "%.41Lg";
if ($cpuarch =~ /^amd64|ia64$/) {
$floattype = 'FLOATTYPE_10';
$nvformat = "%.16Lg";
}
elsif ($cpuarch eq 'mips') {
# quadmath with special NaN
$floattype = 'FLOATTYPE_16MIPS';
}
elsif ($cpuarch eq 'ppc') {
# double-double
$floattype = 'FLOATTYPE_16PPC';
}
elsif ($cpuarch =~ /^s390|sparc/) {
# IEEE-754 quadmath
$floattype = 'FLOATTYPE_16';
}
else {
die qq{Configure.pl: Can't find the binary representation for '$nv'\n};
}
}
$nvformat =~ s/"//g; # Perl 5's Config value has embedded double quotes
}
else {
die qq{Configure.pl: Can't find a printf-style format specifier for type '$nv'\n};
}
else {
die qq{Configure.pl: Can't find a printf-style format specifier for type '$nv'\n};
}
}
elsif ( $nv eq '__float128' ) {
$nvsize = $ldsize;
# TODO probe for it.
$nvformat = "%Qg"; # libquadmath printf hook support (linux only).
$floattype = 'FLOATTYPE_16';
}
elsif ( $nv eq "float" ) {
$nvsize = 4;
$nvformat = "%.7g"; # http://www.keil.com/support/docs/2191.htm
$floattype = 'FLOATTYPE_4';
}
else {
die qq{Configure.pl: Can't find a printf-style format specifier for type '$nv'\n};
}

$conf->data->set(
floatvalfmt => $nvformat,
nvsize => $nvsize
nvsize => $nvsize,
floattype => $floattype
);
}

Expand Down
2 changes: 1 addition & 1 deletion config/auto/sizes.pm
Expand Up @@ -55,7 +55,7 @@ sub runstep {
_handle_ptrcast(
$conf, \%types, $sizes, [ @std_ints, @extra_ints ]);

for ( keys %types ) {
for ( sort keys %types ) {
$conf->data->set( $_.'size' => $sizes->{$types{$_}} );
}

Expand Down
2 changes: 2 additions & 0 deletions config/gen/config_h/config_h.in
Expand Up @@ -151,6 +151,8 @@ typedef void DPOINTER;
#define INTVAL_FMT "@intvalfmt@"
#define FLOATVAL_FMT "@floatvalfmt@"

#define FLOATTYPE @floattype@

#include "parrot/has_header.h"
#include "parrot/feature.h"

Expand Down
30 changes: 1 addition & 29 deletions src/packfile/api.c
Expand Up @@ -1372,35 +1372,7 @@ PackFile_set_header(ARGOUT(PackFile_Header *header))
header->patch = PARROT_PATCH_VERSION;
header->bc_major = PARROT_PBC_MAJOR;
header->bc_minor = PARROT_PBC_MINOR;
#if NUMVAL_SIZE == 8
header->floattype = FLOATTYPE_8; /* IEEE-754 8 byte double */
/* intel 80bit extended precision format, aligned or not */
/* http://sourceforge.net/apps/mediawiki/predef/index.php?title=Architectures#Intel_x86 */
#elif ((NUMVAL_SIZE == 12 || NUMVAL_SIZE == 16) \
&& (defined(i386) || defined(__I86__) || defined(__INTEL__) \
|| defined(_M_IA64) || defined(__ia64__)) \
&& !PARROT_BIGENDIAN)
header->floattype = FLOATTYPE_10;
/* Non-Intel 16 byte quad double */
#elif (NUMVAL_SIZE == 16)
/* This is IEEE-754 Sparc64, also gcc __float128.
TODO: Need to know if i64 uses this format */
header->floattype = FLOATTYPE_16;
# if defined(__mips__)
header->floattype = FLOATTYPE_16MIPS;
# elif (defined(__powerpc) && OPCODE_T_SIZE == 8)
header->floattype = FLOATTYPE_16PPC;
# elif defined(_AIX)
header->floattype = FLOATTYPE_16AIX;
# endif
#elif (NUMVAL_SIZE == 4)
header->floattype = FLOATTYPE_4;
#else
Parrot_x_force_error_exit(NULL, 1,
"PackFile_set_header: Unsupported floattype NUMVAL_SIZE=%d,"
" PARROT_BIGENDIAN=%s\n", NUMVAL_SIZE,
PARROT_BIGENDIAN ? "big-endian" : "little-endian");
#endif
header->floattype = FLOATTYPE;
}


Expand Down
4 changes: 2 additions & 2 deletions t/native_pbc/number.t
Expand Up @@ -109,11 +109,11 @@ my $output2 = << 'END_OUTPUT';
68719476736
274877906944
1099511627776
4398046511104
4.398046511104
17592186044416
70368744177664
281474976710656
1.12589990684262e+15
1125899906842620
END_OUTPUT

my $output = $output2;
Expand Down
Binary file modified t/native_pbc/number_4_12_le.pbc
Binary file not shown.
Binary file modified t/native_pbc/number_8_16_le.pbc
Binary file not shown.
Binary file modified t/native_pbc/number_8_8_le.pbc
Binary file not shown.

0 comments on commit 1cb93a8

Please sign in to comment.