Daily bump.
[gcc.git] / libgo / runtime / go-type-complex.c
1 /* go-type-complex.c -- hash and equality complex 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 64-bit type. */
11
12 typedef unsigned int DItype __attribute__ ((mode (DI)));
13
14 /* Hash function for float types. */
15
16 uintptr_t
17 __go_type_hash_complex (const void *vkey, uintptr_t key_size)
18 {
19 if (key_size == 8)
20 {
21 union
22 {
23 unsigned char a[8];
24 __complex float cf;
25 DItype di;
26 } ucf;
27 __complex float cf;
28 float cfr;
29 float cfi;
30
31 __builtin_memcpy (ucf.a, vkey, 8);
32 cf = ucf.cf;
33 cfr = __builtin_crealf (cf);
34 cfi = __builtin_cimagf (cf);
35 if (__builtin_isinff (cfr) || __builtin_isinff (cfi))
36 return 0;
37
38 /* NaN != NaN, so the hash code of a NaN is irrelevant. Make it
39 random so that not all NaNs wind up in the same place. */
40 if (__builtin_isnanf (cfr) || __builtin_isnanf (cfi))
41 return runtime_fastrand1 ();
42
43 /* Avoid negative zero. */
44 if (cfr == 0 && cfi == 0)
45 return 0;
46 else if (cfr == 0)
47 ucf.cf = cfi * 1.0iF;
48 else if (cfi == 0)
49 ucf.cf = cfr;
50
51 return ucf.di;
52 }
53 else if (key_size == 16)
54 {
55 union
56 {
57 unsigned char a[16];
58 __complex double cd;
59 DItype adi[2];
60 } ucd;
61 __complex double cd;
62 double cdr;
63 double cdi;
64
65 __builtin_memcpy (ucd.a, vkey, 16);
66 cd = ucd.cd;
67 cdr = __builtin_crealf (cd);
68 cdi = __builtin_cimagf (cd);
69 if (__builtin_isinf (cdr) || __builtin_isinf (cdi))
70 return 0;
71
72 if (__builtin_isnan (cdr) || __builtin_isnan (cdi))
73 return runtime_fastrand1 ();
74
75 /* Avoid negative zero. */
76 if (cdr == 0 && cdi == 0)
77 return 0;
78 else if (cdr == 0)
79 ucd.cd = cdi * 1.0i;
80 else if (cdi == 0)
81 ucd.cd = cdr;
82
83 return ucd.adi[0] ^ ucd.adi[1];
84 }
85 else
86 runtime_throw ("__go_type_hash_complex: invalid complex size");
87 }
88
89 /* Equality function for complex types. */
90
91 _Bool
92 __go_type_equal_complex (const void *vk1, const void *vk2, uintptr_t key_size)
93 {
94 if (key_size == 8)
95 {
96 union
97 {
98 unsigned char a[8];
99 __complex float cf;
100 } ucf;
101 __complex float cf1;
102 __complex float cf2;
103
104 __builtin_memcpy (ucf.a, vk1, 8);
105 cf1 = ucf.cf;
106 __builtin_memcpy (ucf.a, vk2, 8);
107 cf2 = ucf.cf;
108 return cf1 == cf2;
109 }
110 else if (key_size == 16)
111 {
112 union
113 {
114 unsigned char a[16];
115 __complex double cd;
116 } ucd;
117 __complex double cd1;
118 __complex double cd2;
119
120 __builtin_memcpy (ucd.a, vk1, 16);
121 cd1 = ucd.cd;
122 __builtin_memcpy (ucd.a, vk2, 16);
123 cd2 = ucd.cd;
124 return cd1 == cd2;
125 }
126 else
127 runtime_throw ("__go_type_equal_complex: invalid complex size");
128 }