2012-01-13 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / libgo / runtime / go-type-complex.c
blobf923c867d99585644a2c3acb028e7b0ead641b82
1 /* go-type-complex.c -- hash and equality complex functions.
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. */
7 #include "runtime.h"
8 #include "go-type.h"
10 /* The 64-bit type. */
12 typedef unsigned int DItype __attribute__ ((mode (DI)));
14 /* Hash function for float types. */
16 uintptr_t
17 __go_type_hash_complex (const void *vkey, uintptr_t key_size)
19 if (key_size == 8)
21 union
23 unsigned char a[8];
24 __complex float cf;
25 DItype di;
26 } ucf;
27 __complex float cf;
28 float cfr;
29 float cfi;
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 || __builtin_isnanf (cfr) || __builtin_isnanf (cfi))
37 return 0;
39 /* Avoid negative zero. */
40 if (cfr == 0 && cfi == 0)
41 return 0;
42 else if (cfr == 0)
43 ucf.cf = cfi * 1.0iF;
44 else if (cfi == 0)
45 ucf.cf = cfr;
47 return ucf.di;
49 else if (key_size == 16)
51 union
53 unsigned char a[16];
54 __complex double cd;
55 DItype adi[2];
56 } ucd;
57 __complex double cd;
58 double cdr;
59 double cdi;
61 __builtin_memcpy (ucd.a, vkey, 16);
62 cd = ucd.cd;
63 cdr = __builtin_crealf (cd);
64 cdi = __builtin_cimagf (cd);
65 if (__builtin_isinf (cdr) || __builtin_isinf (cdi)
66 || __builtin_isnan (cdr) || __builtin_isnan (cdi))
67 return 0;
69 /* Avoid negative zero. */
70 if (cdr == 0 && cdi == 0)
71 return 0;
72 else if (cdr == 0)
73 ucd.cd = cdi * 1.0i;
74 else if (cdi == 0)
75 ucd.cd = cdr;
77 return ucd.adi[0] ^ ucd.adi[1];
79 else
80 runtime_throw ("__go_type_hash_complex: invalid complex size");
83 /* Equality function for complex types. */
85 _Bool
86 __go_type_equal_complex (const void *vk1, const void *vk2, uintptr_t key_size)
88 if (key_size == 8)
90 union
92 unsigned char a[8];
93 __complex float cf;
94 } ucf;
95 __complex float cf1;
96 __complex float cf2;
98 __builtin_memcpy (ucf.a, vk1, 8);
99 cf1 = ucf.cf;
100 __builtin_memcpy (ucf.a, vk2, 8);
101 cf2 = ucf.cf;
102 return cf1 == cf2;
104 else if (key_size == 16)
106 union
108 unsigned char a[16];
109 __complex double cd;
110 } ucd;
111 __complex double cd1;
112 __complex double cd2;
114 __builtin_memcpy (ucd.a, vk1, 16);
115 cd1 = ucd.cd;
116 __builtin_memcpy (ucd.a, vk2, 16);
117 cd2 = ucd.cd;
118 return cd1 == cd2;
120 else
121 runtime_throw ("__go_type_equal_complex: invalid complex size");