OSDN Git Service

compiler, runtime: Reject surrogate pair converting int to string.
[pf3gnuchains/gcc-fork.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) || f == 0)
33         return 0;
34
35       /* NaN != NaN, so the hash code of a NaN is irrelevant.  Make it
36          random so that not all NaNs wind up in the same place.  */
37       if (__builtin_isnanf (f))
38         return runtime_fastrand1 ();
39
40       return (uintptr_t) uf.si;
41     }
42   else if (key_size == 8)
43     {
44       union
45       {
46         unsigned char a[8];
47         double d;
48         DItype di;
49       } ud;
50       double d;
51
52       __builtin_memcpy (ud.a, vkey, 8);
53       d = ud.d;
54       if (__builtin_isinf (d) || d == 0)
55         return 0;
56
57       if (__builtin_isnan (d))
58         return runtime_fastrand1 ();
59
60       return (uintptr_t) ud.di;
61     }
62   else
63     runtime_throw ("__go_type_hash_float: invalid float size");
64 }
65
66 /* Equality function for float types.  */
67
68 _Bool
69 __go_type_equal_float (const void *vk1, const void *vk2, uintptr_t key_size)
70 {
71   if (key_size == 4)
72     {
73       union
74       {
75         unsigned char a[4];
76         float f;
77       } uf;
78       float f1;
79       float f2;
80
81       __builtin_memcpy (uf.a, vk1, 4);
82       f1 = uf.f;
83       __builtin_memcpy (uf.a, vk2, 4);
84       f2 = uf.f;
85       return f1 == f2;
86     }
87   else if (key_size == 8)
88     {
89       union
90       {
91         unsigned char a[8];
92         double d;
93         DItype di;
94       } ud;
95       double d1;
96       double d2;
97
98       __builtin_memcpy (ud.a, vk1, 8);
99       d1 = ud.d;
100       __builtin_memcpy (ud.a, vk2, 8);
101       d2 = ud.d;
102       return d1 == d2;
103     }
104   else
105     runtime_throw ("__go_type_equal_float: invalid float size");
106 }