Skip to content

Commit

Permalink
Add a probe for signbit and use it to implement MVM_num_isnegzero
Browse files Browse the repository at this point in the history
  • Loading branch information
nwc10 committed May 8, 2021
1 parent 86e1289 commit d602912
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 2 deletions.
4 changes: 4 additions & 0 deletions build/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@
#define MVM_HAS_ISNAN
#endif

#if @has_signbit@
#define MVM_HAS_SIGNBIT
#endif

/* Should we translate \n to \r\n on output? */
#define MVM_TRANSLATE_NEWLINE_OUTPUT @translate_newline_output@

Expand Down
13 changes: 11 additions & 2 deletions build/probe.pm
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,8 @@ EOT
}

my @floating_point_vals = qw(zero one nan inf neg_inf neg_zero
int_less_than_minus_one int_more_than_one);
int_less_than_minus_one int_more_than_one
roughly_ten roughly_minus_ten);

my $floating_point_main = <<'EOT';
#include <math.h>
Expand All @@ -402,12 +403,14 @@ int main(int argc, char **argv) {
*/
double zero = argv[0][0] == '\0';
double one = zero + 1.0;
double nan = sqrt(-1);
double int_less_than_minus_one = 34 - argv[0][0];
double int_more_than_one = argv[0][0] - 30;
double inf = int_more_than_one * pow(10.0, pow(10.0, 100));
double neg_inf = int_less_than_minus_one * pow(10.0, pow(10.0, 100));
double neg_zero = one / neg_inf;
double roughly_ten = atan2(zero, -one) * atan2(zero, -one);
double roughly_minus_ten = -roughly_ten;
double nan = sqrt(roughly_minus_ten);
if (zero) {
#ifdef CHATTY
Expand Down Expand Up @@ -734,6 +737,7 @@ sub has_isinf_and_isnan {
my @probes = (
[ isnan => 'nan' ],
[ isinf => qw(inf neg_inf) ],
[ signbit => qw(neg_inf neg_zero int_less_than_minus_one roughly_minus_ten)],
);

if ($config->{crossconf}) {
Expand All @@ -754,6 +758,11 @@ sub has_isinf_and_isnan {
my $exit = 11;

for my $val (@floating_point_vals) {
# NaNs can actually have sign bits, so the sign bit might/might not
# be set, and we can't know (and shouldn't care):
next
if $func eq 'signbit' && $val eq 'nan';

my $want = $true{$val} ? 'T' : 'f';

$code .= <<"EOT";
Expand Down
4 changes: 4 additions & 0 deletions src/math/num.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ MVM_STATIC_INLINE MVMnum64 MVM_num_nan(MVMThreadContext *tc) {
}

MVM_STATIC_INLINE MVMnum64 MVM_num_isnegzero(MVMThreadContext *tc, MVMnum64 n) {
#ifdef MVM_HAS_SIGNBIT
return n == 0 && signbit(n);
#else
return n == 0 && 1.0 / n == MVM_NUM_NEGINF;
#endif
}

#endif

0 comments on commit d602912

Please sign in to comment.