Retro68/gcc/libgo/runtime/go-type-float.c

93 lines
1.9 KiB
C
Raw Normal View History

2012-03-27 23:13:14 +00:00
/* go-type-float.c -- hash and equality float functions.
Copyright 2012 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file. */
2015-08-28 15:33:40 +00:00
#include <math.h>
#include <stdint.h>
2012-03-27 23:13:14 +00:00
#include "runtime.h"
#include "go-type.h"
/* Hash function for float types. */
uintptr_t
__go_type_hash_float (const void *vkey, uintptr_t key_size)
{
if (key_size == 4)
{
2015-08-28 15:33:40 +00:00
const float *fp;
2012-03-27 23:13:14 +00:00
float f;
2015-08-28 15:33:40 +00:00
uint32_t si;
2012-03-27 23:13:14 +00:00
2015-08-28 15:33:40 +00:00
fp = (const float *) vkey;
f = *fp;
if (isinf (f) || f == 0)
2012-03-27 23:13:14 +00:00
return 0;
2014-09-21 17:33:12 +00:00
/* NaN != NaN, so the hash code of a NaN is irrelevant. Make it
random so that not all NaNs wind up in the same place. */
2015-08-28 15:33:40 +00:00
if (isnan (f))
2014-09-21 17:33:12 +00:00
return runtime_fastrand1 ();
2015-08-28 15:33:40 +00:00
memcpy (&si, vkey, 4);
return (uintptr_t) si;
2012-03-27 23:13:14 +00:00
}
else if (key_size == 8)
{
2015-08-28 15:33:40 +00:00
const double *dp;
2012-03-27 23:13:14 +00:00
double d;
2015-08-28 15:33:40 +00:00
uint64_t di;
dp = (const double *) vkey;
d = *dp;
2012-03-27 23:13:14 +00:00
2015-08-28 15:33:40 +00:00
if (isinf (d) || d == 0)
2012-03-27 23:13:14 +00:00
return 0;
2014-09-21 17:33:12 +00:00
2015-08-28 15:33:40 +00:00
if (isnan (d))
2014-09-21 17:33:12 +00:00
return runtime_fastrand1 ();
2015-08-28 15:33:40 +00:00
memcpy (&di, vkey, 8);
return (uintptr_t) di;
2012-03-27 23:13:14 +00:00
}
else
runtime_throw ("__go_type_hash_float: invalid float size");
}
2017-04-10 11:32:00 +00:00
const FuncVal __go_type_hash_float_descriptor =
{ (void *) __go_type_hash_float };
2012-03-27 23:13:14 +00:00
/* Equality function for float types. */
_Bool
__go_type_equal_float (const void *vk1, const void *vk2, uintptr_t key_size)
{
if (key_size == 4)
{
2015-08-28 15:33:40 +00:00
const float *fp1;
const float *fp2;
fp1 = (const float *) vk1;
fp2 = (const float *) vk2;
return *fp1 == *fp2;
2012-03-27 23:13:14 +00:00
}
else if (key_size == 8)
{
2015-08-28 15:33:40 +00:00
const double *dp1;
const double *dp2;
dp1 = (const double *) vk1;
dp2 = (const double *) vk2;
return *dp1 == *dp2;
2012-03-27 23:13:14 +00:00
}
else
runtime_throw ("__go_type_equal_float: invalid float size");
}
2017-04-10 11:32:00 +00:00
const FuncVal __go_type_equal_float_descriptor =
{ (void *) __go_type_equal_float };