Skip to content

Commit

Permalink
Merge branch 'solaris'
Browse files Browse the repository at this point in the history
  • Loading branch information
nwc10 committed Dec 29, 2020
2 parents b8663f5 + 5e031c9 commit 78f4f1d
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Configure.pl
Original file line number Diff line number Diff line change
Expand Up @@ -491,13 +491,15 @@ sub uniq {
build::auto::detect_cross(\%config, \%defaults);
build::probe::static_inline_cross(\%config, \%defaults);
build::probe::thread_local_cross(\%config, \%defaults);
build::probe::substandard_pow_cross(\%config, \%defaults);
build::probe::unaligned_access_cross(\%config, \%defaults);
build::probe::ptr_size_cross(\%config, \%defaults);
}
else {
build::auto::detect_native(\%config, \%defaults);
build::probe::static_inline_native(\%config, \%defaults);
build::probe::thread_local_native(\%config, \%defaults);
build::probe::substandard_pow(\%config, \%defaults);
build::probe::unaligned_access(\%config, \%defaults);
build::probe::ptr_size_native(\%config, \%defaults);
}
Expand Down
1 change: 1 addition & 0 deletions build/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ UV_DARWIN = 3rdparty/libuv/src/unix/darwin@obj@ \
$(UV_UNIX)

UV_SOLARIS = 3rdparty/libuv/src/unix/sunos@obj@ \
3rdparty/libuv/src/unix/no-proctitle@obj@ \
$(UV_UNIX)

UV_AIX = 3rdparty/libuv/src/unix/aix@obj@ \
Expand Down
3 changes: 3 additions & 0 deletions build/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@

#define MVM_PTR_SIZE @ptr_size@

#if @has_substandard_pow@
#define MVM_HAS_SUBSTANDARD_POW
#endif

#if @havebooltype@
#define MVM_BOOL @booltype@
Expand Down
116 changes: 116 additions & 0 deletions build/probe.pm
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,122 @@ EOT
}
}

sub substandard_pow_cross {
my ($config) = @_;
$config->{has_substandard_pow} = 0;
}

sub substandard_pow {
my ($config) = @_;
my $restore = _to_probe_dir();
print ::dots(' probing if your pow() handles NaN and Inf corner cases');
my $file = 'try.c';
_spew($file, <<'EOT');
#include <math.h>
#include <stdio.h>
int main(int argc, char **argv) {
/* Hopefully these games defeat the optimiser, such that we call the runtime
* library pow, instead of having the C compiler optimiser constant fold it.
* Without this (for me on Solaris with gcc)
* pow(1.0, NaN) will be constant folded always
* pow(1.0, Inf) will be constant folded if optimisation is enabled
*/
double one = argv[0][0] != '\0';
double zero = one - 1.0;
double nan = sqrt(-1);
if (nan == nan) {
#ifdef CHATTY
fprintf(stderr, "Can't generate NaN - get %g\n", nan);
#endif
return 1;
}
double inf = pow(10.0, pow(10.0, 100));
if (inf != 2.0 * inf) {
#ifdef CHATTY
fprintf(stderr, "Can't generate Inf - get %g\n", inf);
#endif
return 2;
}
double neg_inf = -inf;
if (! (neg_inf < 0.0)) {
#ifdef CHATTY
fprintf(stderr, "Can't generate -Inf - get %g\n", inf);
#endif
return 3;
}
if (neg_inf != 2.0 * neg_inf) {
#ifdef CHATTY
fprintf(stderr, "Can't generate -Inf - get %g\n", inf);
#endif
return 4;
}
/* Solaris is documented not to be conformant with SUSv3 (which I think
* is POSIX 2001) unless
* "the application was compiled with the c99 compiler driver"
* which as best I can tell gcc doesn't, even with -std=c99 */
double got = pow(one, nan);
if (got != one) {
#ifdef CHATTY
fprintf(stderr, "1.0, NaN: pow(%g, %g) is %g, not 1.0\n", one, nan, got);
#endif
return 5;
}
got = pow(one, inf);
if (got != one) {
#ifdef CHATTY
fprintf(stderr, "1.0, Inf: pow(%g, %g) is %g, not 1.0\n", one, inf, got);
#endif
return 6;
}
got = pow(one, neg_inf);
if (got != one) {
#ifdef CHATTY
fprintf(stderr, "1.0, -Inf: pow(%g, %g) is %g, not 1.0\n", one, neg_inf, got);
#endif
return 7;
}
/* However, Solaris does state that unconditionally:
* For any value of x (including NaN), if y is +0, 1.0 is returned.
* (without repeating that caveat about the c99 compiler driver)
* and yet behaviour of gcc and *Solaris* studio is consistent in returning
* NaN for pow(NaN, 0.0). Oracle studio seems to default to c99.
*/
got = pow(nan, zero);
if (got != one) {
#ifdef CHATTY
fprintf(stderr, "NaN, 0.0: pow(%g, %g) is %g, not 1.0\n", nan, zero, got);
#endif
return 8;
}
/* Not seen either of these fail anywhere, but let's test anyway: */
got = pow(inf, zero);
if (got != one) {
#ifdef CHATTY
fprintf(stderr, "Inf, 0.0: pow(%g, %g) is %g, not 1.0\n", inf, zero, got);
#endif
return 9;
}
got = pow(neg_inf, zero);
if (got != one) {
#ifdef CHATTY
fprintf(stderr, "-Inf, 0.0: pow(%g, %g) is %g, not 1.0\n", neg_inf, zero, got);
#endif
return 10;
}
return 0;
}
EOT

my $pow_good = compile($config, 'try') && system('./try') == 0;
print $pow_good ? "YES\n": "NO\n";
$config->{has_substandard_pow} = $pow_good ? 0 : 1;
}


sub specific_werror {
my ($config) = @_;
my $restore = _to_probe_dir();
Expand Down
2 changes: 1 addition & 1 deletion build/setup.pm
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ my $devnull = devnull();
our %TP_LAO = (
name => 'atomic_ops',
path => '3rdparty/libatomicops/src',
rule => 'cd 3rdparty/libatomicops && CC=\'$(CC)\' CFLAGS=\'$(CFLAGS)\' ./configure @crossconf@ && cd src && $(MAKE) && cd ..',
rule => 'cd 3rdparty/libatomicops && CC=\'$(CC)\' CFLAGS=\'$(CFLAGS)\' MAKE=\'$(MAKE)\' ./configure @crossconf@ && cd src && $(MAKE) && cd ..',
clean => 'cd 3rdparty/libatomicops/src && $(MAKE) distclean',
);

Expand Down
11 changes: 9 additions & 2 deletions src/core/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,10 +800,17 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
GET_REG(cur_op, 0).n64 = fabs(GET_REG(cur_op, 2).n64);
cur_op += 4;
goto NEXT;
OP(pow_n):
GET_REG(cur_op, 0).n64 = pow(GET_REG(cur_op, 2).n64, GET_REG(cur_op, 4).n64);
OP(pow_n): {
MVMnum64 x = GET_REG(cur_op, 2).n64;
MVMnum64 y = GET_REG(cur_op, 4).n64;
GET_REG(cur_op, 0).n64 =
#ifdef MVM_HAS_SUBSTANDARD_POW
y == 0.0 || x == 1.0 ? 1.0 :
#endif
pow(x, y);
cur_op += 6;
goto NEXT;
}
OP(ceil_n):
GET_REG(cur_op, 0).n64 = ceil(GET_REG(cur_op, 2).n64);
cur_op += 4;
Expand Down
4 changes: 4 additions & 0 deletions src/jit/graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,9 @@ static void * op_to_func(MVMThreadContext *tc, MVMint16 opcode) {
case MVM_OP_pow_I: return MVM_bigint_pow;
case MVM_OP_rand_I: return MVM_bigint_rand;
case MVM_OP_abs_n: return fabs;
#ifndef MVM_HAS_SUBSTANDARD_POW
case MVM_OP_pow_n: return pow;
#endif
case MVM_OP_time_n: return MVM_proc_time_n;
case MVM_OP_randscale_n: return MVM_proc_randscale_n;
case MVM_OP_isnanorinf: return MVM_num_isnanorinf;
Expand Down Expand Up @@ -3511,7 +3513,9 @@ static MVMint32 consume_ins(MVMThreadContext *tc, MVMJitGraph *jg,
MVM_JIT_RV_NUM, dst);
break;
}
#ifndef MVM_HAS_SUBSTANDARD_POW
case MVM_OP_pow_n:
#endif
case MVM_OP_atan2_n: {
MVMint16 dst = ins->operands[0].reg.orig;
MVMint16 a = ins->operands[1].reg.orig;
Expand Down
4 changes: 4 additions & 0 deletions src/strings/siphash/csiphash.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ typedef struct siphash siphash;
# include <libkern/OSByteOrder.h>
# define MVM_TO_LITTLE_ENDIAN_64(x) OSSwapLittleToHostInt64(x)
# define MVM_TO_LITTLE_ENDIAN_32(x) OSSwapLittleToHostInt32(x)
#elif defined(__sun)
# include <sys/byteorder.h>
# define MVM_TO_LITTLE_ENDIAN_64(x) LE_64(x)
# define MVM_TO_LITTLE_ENDIAN_32(x) LE_32(x)
#else
/* See: http://sourceforge.net/p/predef/wiki/Endianness/ */
# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
Expand Down

0 comments on commit 78f4f1d

Please sign in to comment.