* sr.po: Update.
[official-gcc.git] / libgo / runtime / go-type-complex.c
blob585984e9fef220c1c58521ef6a3149530f88ef5b
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 <complex.h>
8 #include <math.h>
9 #include <stdint.h>
10 #include <string.h>
11 #include "runtime.h"
12 #include "go-type.h"
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 const complex float *cfp;
22 complex float cf;
23 float cfr;
24 float cfi;
25 uint64_t fi;
27 cfp = (const complex float *) vkey;
28 cf = *cfp;
30 cfr = crealf (cf);
31 cfi = cimagf (cf);
33 if (isinf (cfr) || isinf (cfi))
34 return 0;
36 /* NaN != NaN, so the hash code of a NaN is irrelevant. Make it
37 random so that not all NaNs wind up in the same place. */
38 if (isnan (cfr) || isnan (cfi))
39 return runtime_fastrand1 ();
41 /* Avoid negative zero. */
42 if (cfr == 0 && cfi == 0)
43 return 0;
44 else if (cfr == 0)
45 cf = cfi * I;
46 else if (cfi == 0)
47 cf = cfr;
49 memcpy (&fi, &cf, 8);
50 return (uintptr_t) cfi;
52 else if (key_size == 16)
54 const complex double *cdp;
55 complex double cd;
56 double cdr;
57 double cdi;
58 uint64_t di[2];
60 cdp = (const complex double *) vkey;
61 cd = *cdp;
63 cdr = creal (cd);
64 cdi = cimag (cd);
66 if (isinf (cdr) || isinf (cdi))
67 return 0;
69 if (isnan (cdr) || isnan (cdi))
70 return runtime_fastrand1 ();
72 /* Avoid negative zero. */
73 if (cdr == 0 && cdi == 0)
74 return 0;
75 else if (cdr == 0)
76 cd = cdi * I;
77 else if (cdi == 0)
78 cd = cdr;
80 memcpy (&di, &cd, 16);
81 return di[0] ^ di[1];
83 else
84 runtime_throw ("__go_type_hash_complex: invalid complex size");
87 const FuncVal __go_type_hash_complex_descriptor =
88 { (void *) __go_type_hash_complex };
90 /* Equality function for complex types. */
92 _Bool
93 __go_type_equal_complex (const void *vk1, const void *vk2, uintptr_t key_size)
95 if (key_size == 8)
97 const complex float *cfp1;
98 const complex float *cfp2;
100 cfp1 = (const complex float *) vk1;
101 cfp2 = (const complex float *) vk2;
103 return *cfp1 == *cfp2;
105 else if (key_size == 16)
107 const complex double *cdp1;
108 const complex double *cdp2;
110 cdp1 = (const complex double *) vk1;
111 cdp2 = (const complex double *) vk2;
113 return *cdp1 == *cdp2;
115 else
116 runtime_throw ("__go_type_equal_complex: invalid complex size");
119 const FuncVal __go_type_equal_complex_descriptor =
120 { (void *) __go_type_equal_complex };