mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			93 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C
		
	
	
	
| /* go-type-float.c -- hash and equality float functions.
 | |
| 
 | |
|    Copyright 2012 The Go Authors. All rights reserved.
 | |
|    Use of this source code is governed by a BSD-style
 | |
|    license that can be found in the LICENSE file.  */
 | |
| 
 | |
| #include <math.h>
 | |
| #include <stdint.h>
 | |
| #include "runtime.h"
 | |
| #include "go-type.h"
 | |
| 
 | |
| /* Hash function for float types.  */
 | |
| 
 | |
| uintptr_t
 | |
| __go_type_hash_float (const void *vkey, uintptr_t key_size)
 | |
| {
 | |
|   if (key_size == 4)
 | |
|     {
 | |
|       const float *fp;
 | |
|       float f;
 | |
|       uint32_t si;
 | |
| 
 | |
|       fp = (const float *) vkey;
 | |
|       f = *fp;
 | |
| 
 | |
|       if (isinf (f) || f == 0)
 | |
| 	return 0;
 | |
| 
 | |
|       /* NaN != NaN, so the hash code of a NaN is irrelevant.  Make it
 | |
| 	 random so that not all NaNs wind up in the same place.  */
 | |
|       if (isnan (f))
 | |
| 	return runtime_fastrand1 ();
 | |
| 
 | |
|       memcpy (&si, vkey, 4);
 | |
|       return (uintptr_t) si;
 | |
|     }
 | |
|   else if (key_size == 8)
 | |
|     {
 | |
|       const double *dp;
 | |
|       double d;
 | |
|       uint64_t di;
 | |
| 
 | |
|       dp = (const double *) vkey;
 | |
|       d = *dp;
 | |
| 
 | |
|       if (isinf (d) || d == 0)
 | |
| 	return 0;
 | |
| 
 | |
|       if (isnan (d))
 | |
| 	return runtime_fastrand1 ();
 | |
| 
 | |
|       memcpy (&di, vkey, 8);
 | |
|       return (uintptr_t) di;
 | |
|     }
 | |
|   else
 | |
|     runtime_throw ("__go_type_hash_float: invalid float size");
 | |
| }
 | |
| 
 | |
| const FuncVal __go_type_hash_float_descriptor =
 | |
|   { (void *) __go_type_hash_float };
 | |
| 
 | |
| /* Equality function for float types.  */
 | |
| 
 | |
| _Bool
 | |
| __go_type_equal_float (const void *vk1, const void *vk2, uintptr_t key_size)
 | |
| {
 | |
|   if (key_size == 4)
 | |
|     {
 | |
|       const float *fp1;
 | |
|       const float *fp2;
 | |
| 
 | |
|       fp1 = (const float *) vk1;
 | |
|       fp2 = (const float *) vk2;
 | |
| 
 | |
|       return *fp1 == *fp2;
 | |
|     }
 | |
|   else if (key_size == 8)
 | |
|     {
 | |
|       const double *dp1;
 | |
|       const double *dp2;
 | |
| 
 | |
|       dp1 = (const double *) vk1;
 | |
|       dp2 = (const double *) vk2;
 | |
| 
 | |
|       return *dp1 == *dp2;
 | |
|     }
 | |
|   else
 | |
|     runtime_throw ("__go_type_equal_float: invalid float size");
 | |
| }
 | |
| 
 | |
| const FuncVal __go_type_equal_float_descriptor =
 | |
|   { (void *) __go_type_equal_float };
 |