OSDN Git Service

libgo: Solaris and Irix compatibility patches.
[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) || __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 }