5
5
* reserved.
6
6
* Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
7
7
* Copyright (c) 2015-2017 Research Organization for Information Science
8
+ * Copyright (c) 2015-2017 Research Organization for Information Science
8
9
* and Technology (RIST). All rights reserved.
9
10
* $COPYRIGHT$
10
11
*
15
16
16
17
#include "opal_config.h"
17
18
19
+ #ifdef HAVE_IEEE754_H
20
+ #include <ieee754.h>
21
+ #endif
22
+
18
23
#include <stddef.h>
19
24
#include <stdint.h>
20
25
@@ -62,13 +67,74 @@ opal_dt_swap_bytes(void *to_p, const void *from_p, const size_t size, size_t cou
62
67
}
63
68
}
64
69
70
+ #ifdef HAVE_IEEE754_H
71
+ struct bit128 {
72
+ unsigned int mantissa3 :32 ;
73
+ unsigned int mantissa2 :32 ;
74
+ unsigned int mantissa1 :32 ;
75
+ unsigned int mantissa0 :16 ;
76
+ unsigned int exponent :15 ;
77
+ unsigned int negative :1 ;
78
+ };
79
+
80
+ struct bit80 {
81
+ unsigned int pad :32 ;
82
+ unsigned int empty :16 ;
83
+ unsigned int negative :1 ;
84
+ unsigned int exponent :15 ;
85
+ unsigned int mantissa0 :32 ;
86
+ unsigned int mantissa1 :32 ;
87
+ };
88
+
89
+ static inline void
90
+ opal_dt_swap_long_double (void * to_p , const void * from_p , const size_t size , size_t count , uint32_t remoteArch )
91
+ {
92
+ size_t i ;
93
+ long double * to = (long double * ) to_p ;
94
+
95
+ if ((opal_local_arch & OPAL_ARCH_LDISINTEL ) && !(remoteArch & OPAL_ARCH_LDISINTEL )) {
96
+ #ifdef __x86_64
97
+ for (i = 0 ; i < count ; i ++ , to ++ ) {
98
+ union ieee854_long_double ld ;
99
+ struct bit128 * b = (struct bit128 * )to ;
100
+ ld .ieee .empty = 0 ;
101
+ ld .ieee .mantissa0 = 0x80000000 | (((unsigned int )b -> mantissa0 << 15 ) & 0x7FFF8000 ) | ((b -> mantissa1 >> 17 ) & 0x00007FFF );
102
+ ld .ieee .mantissa1 = ((b -> mantissa1 << 15 ) & 0xFFFF8000 ) | ((b -> mantissa2 << 17 ) & 0x000007FFF );
103
+ ld .ieee .exponent = b -> exponent ;
104
+ ld .ieee .negative = b -> negative ;
105
+ MEMCPY ( to , & ld , sizeof (long double ));
106
+ }
107
+ #endif
108
+ } else if (!(opal_local_arch & OPAL_ARCH_LDISINTEL ) && (remoteArch & OPAL_ARCH_LDISINTEL )) {
109
+ #ifdef __sparcv9
110
+ for (i = 0 ; i < count ; i ++ , to ++ ) {
111
+ union ieee854_long_double ld ;
112
+ struct bit80 * b = (struct bit80 * )to ;
113
+ ld .ieee .mantissa3 = 0 ;
114
+ ld .ieee .mantissa2 = 0 ;
115
+ ld .ieee .mantissa0 = (b -> mantissa0 << 1 ) | (b -> mantissa1 & 0x80000000 );
116
+ ld .ieee .mantissa1 = (b -> mantissa1 << 1 ) & 0xFFFFFFFE ;
117
+ ld .ieee .exponent = b -> exponent ;
118
+ ld .ieee .negative = b -> negative ;
119
+ MEMCPY ( to , & ld , sizeof (long double ));
120
+ }
121
+ #endif
122
+ }
123
+ }
124
+ #else
125
+ #define opal_dt_swap_long_double (to_p , from_p , size , count , remoteArch )
126
+ #endif
127
+
65
128
/**
66
129
* BEWARE: Do not use the following macro with composed types such as
67
130
* complex. As the swap is done using the entire type sizeof, the
68
131
* wrong endianess translation will be done. Instead, use the
69
132
* COPY_2SAMETYPE_HETEROGENEOUS.
70
133
*/
71
134
#define COPY_TYPE_HETEROGENEOUS ( TYPENAME , TYPE ) \
135
+ COPY_TYPE_HETEROGENEOUS_INTERNAL( TYPENAME, TYPE, 0 )
136
+
137
+ #define COPY_TYPE_HETEROGENEOUS_INTERNAL ( TYPENAME , TYPE , LONG_DOUBLE ) \
72
138
static int32_t \
73
139
copy_##TYPENAME##_heterogeneous(opal_convertor_t *pConvertor, uint32_t count, \
74
140
const char* from, size_t from_len, ptrdiff_t from_extent, \
@@ -85,9 +151,15 @@ copy_##TYPENAME##_heterogeneous(opal_convertor_t *pConvertor, uint32_t count,
85
151
(opal_local_arch & OPAL_ARCH_ISBIGENDIAN)) { \
86
152
if( (to_extent == from_extent) && (to_extent == sizeof(TYPE)) ) { \
87
153
opal_dt_swap_bytes(to, from, sizeof(TYPE), count); \
154
+ if (LONG_DOUBLE) { \
155
+ opal_dt_swap_long_double(to, from, sizeof(TYPE), count, pConvertor->remoteArch);\
156
+ } \
88
157
} else { \
89
158
for( i = 0; i < count; i++ ) { \
90
159
opal_dt_swap_bytes(to, from, sizeof(TYPE), 1); \
160
+ if (LONG_DOUBLE) { \
161
+ opal_dt_swap_long_double(to, from, sizeof(TYPE), 1, pConvertor->remoteArch);\
162
+ } \
91
163
to += to_extent; \
92
164
from += from_extent; \
93
165
} \
@@ -108,6 +180,9 @@ copy_##TYPENAME##_heterogeneous(opal_convertor_t *pConvertor, uint32_t count,
108
180
}
109
181
110
182
#define COPY_2SAMETYPE_HETEROGENEOUS ( TYPENAME , TYPE ) \
183
+ COPY_2SAMETYPE_HETEROGENEOUS_INTERNAL( TYPENAME, TYPE, 0)
184
+
185
+ #define COPY_2SAMETYPE_HETEROGENEOUS_INTERNAL ( TYPENAME , TYPE , LONG_DOUBLE ) \
111
186
static int32_t \
112
187
copy_##TYPENAME##_heterogeneous(opal_convertor_t *pConvertor, uint32_t count, \
113
188
const char* from, size_t from_len, ptrdiff_t from_extent, \
@@ -122,11 +197,17 @@ copy_##TYPENAME##_heterogeneous(opal_convertor_t *pConvertor, uint32_t count,
122
197
\
123
198
if ((pConvertor->remoteArch & OPAL_ARCH_ISBIGENDIAN) != \
124
199
(opal_local_arch & OPAL_ARCH_ISBIGENDIAN)) { \
125
- if( (to_extent == from_extent) && (to_extent == sizeof(TYPE)) ) { \
200
+ if( (to_extent == from_extent) && (to_extent == (2 * sizeof(TYPE) )) ) { \
126
201
opal_dt_swap_bytes(to, from, sizeof(TYPE), 2 * count); \
202
+ if (LONG_DOUBLE) { \
203
+ opal_dt_swap_long_double(to, from, sizeof(TYPE), 2*count, pConvertor->remoteArch);\
204
+ } \
127
205
} else { \
128
206
for( i = 0; i < count; i++ ) { \
129
207
opal_dt_swap_bytes(to, from, sizeof(TYPE), 2); \
208
+ if (LONG_DOUBLE) { \
209
+ opal_dt_swap_long_double(to, from, sizeof(TYPE), 2, pConvertor->remoteArch);\
210
+ } \
130
211
to += to_extent; \
131
212
from += from_extent; \
132
213
} \
@@ -333,7 +414,7 @@ COPY_TYPE_HETEROGENEOUS( float16, float )
333
414
#elif SIZEOF_DOUBLE == 16
334
415
COPY_TYPE_HETEROGENEOUS ( float16 , double )
335
416
#elif HAVE_LONG_DOUBLE && SIZEOF_LONG_DOUBLE == 16
336
- COPY_TYPE_HETEROGENEOUS ( float16 , long double )
417
+ COPY_TYPE_HETEROGENEOUS_INTERNAL ( float16 , long double , 1 )
337
418
#else
338
419
/* #error No basic type for copy function for opal_datatype_float16 found */
339
420
#define copy_float16_heterogeneous NULL
@@ -354,7 +435,7 @@ COPY_2SAMETYPE_HETEROGENEOUS( double_complex, double )
354
435
#endif
355
436
356
437
#if HAVE_LONG_DOUBLE__COMPLEX
357
- COPY_2SAMETYPE_HETEROGENEOUS ( long_double_complex , long double )
438
+ COPY_2SAMETYPE_HETEROGENEOUS_INTERNAL ( long_double_complex , long double , 1 )
358
439
#else
359
440
/* #error No basic type for copy function for opal_datatype_long_double_complex found */
360
441
#define copy_long_double_complex_heterogeneous NULL
0 commit comments