runtime: correct a logic error in hashmap growth.
[gcc.git] / libgo / runtime / go-type-float.c
1 /* go-type-float.c -- hash and equality float functions.
2
3 Copyright 2012 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
6
7 #include "runtime.h"
8 #include "go-type.h"
9
10 /* The 32-bit and 64-bit types. */
11
12 typedef unsigned int SItype __attribute__ ((mode (SI)));
13 typedef unsigned int DItype __attribute__ ((mode (DI)));
14
15 /* Hash function for float types. */
16
17 uintptr_t
18 __go_type_hash_float (const void *vkey, uintptr_t key_size)
19 {
20 if (key_size == 4)
21 {
22 union
23 {
24 unsigned char a[4];
25 float f;
26 SItype si;
27 } uf;
28 float f;
29
30 __builtin_memcpy (uf.a, vkey, 4);
31 f = uf.f;
32 if (__builtin_isinff (f) || __builtin_isnanf (f) || f == 0)
33 return 0;
34 return (uintptr_t) uf.si;
35 }
36 else if (key_size == 8)
37 {
38 union
39 {
40 unsigned char a[8];
41 double d;
42 DItype di;
43 } ud;
44 double d;
45
46 __builtin_memcpy (ud.a, vkey, 8);
47 d = ud.d;
48 if (__builtin_isinf (d) || __builtin_isnan (d) || d == 0)
49 return 0;
50 return (uintptr_t) ud.di;
51 }
52 else
53 runtime_throw ("__go_type_hash_float: invalid float size");
54 }
55
56 /* Equality function for float types. */
57
58 _Bool
59 __go_type_equal_float (const void *vk1, const void *vk2, uintptr_t key_size)
60 {
61 if (key_size == 4)
62 {
63 union
64 {
65 unsigned char a[4];
66 float f;
67 } uf;
68 float f1;
69 float f2;
70
71 __builtin_memcpy (uf.a, vk1, 4);
72 f1 = uf.f;
73 __builtin_memcpy (uf.a, vk2, 4);
74 f2 = uf.f;
75 return f1 == f2;
76 }
77 else if (key_size == 8)
78 {
79 union
80 {
81 unsigned char a[8];
82 double d;
83 DItype di;
84 } ud;
85 double d1;
86 double d2;
87
88 __builtin_memcpy (ud.a, vk1, 8);
89 d1 = ud.d;
90 __builtin_memcpy (ud.a, vk2, 8);
91 d2 = ud.d;
92 return d1 == d2;
93 }
94 else
95 runtime_throw ("__go_type_equal_float: invalid float size");
96 }