55 * reserved.
66 * Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
77 * Copyright (c) 2015-2017 Research Organization for Information Science
8+ * Copyright (c) 2015-2017 Research Organization for Information Science
89 * and Technology (RIST). All rights reserved.
910 * $COPYRIGHT$
1011 *
1516
1617#include "opal_config.h"
1718
19+ #ifdef HAVE_IEEE754_H
20+ #include <ieee754.h>
21+ #endif
22+
1823#include <stddef.h>
1924#include <stdint.h>
2025
@@ -62,13 +67,78 @@ opal_dt_swap_bytes(void *to_p, const void *from_p, const size_t size, size_t cou
6267 }
6368}
6469
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+ #ifdef HAVE_IEEE754_H
93+ size_t i ;
94+ long double * to = (long double * ) to_p ;
95+
96+ if ((opal_local_arch & OPAL_ARCH_LDISINTEL ) && !(remoteArch & OPAL_ARCH_LDISINTEL )) {
97+ #ifdef __x86_64
98+ for (i = 0 ; i < count ; i ++ , to ++ ) {
99+ union ieee854_long_double ld ;
100+ struct bit128 * b = (struct bit128 * )to ;
101+ ld .ieee .empty = 0 ;
102+ ld .ieee .mantissa0 = 0x80000000 | (((unsigned int )b -> mantissa0 << 15 ) & 0x7FFF8000 ) | ((b -> mantissa1 >> 17 ) & 0x00007FFF );
103+ ld .ieee .mantissa1 = ((b -> mantissa1 << 15 ) & 0xFFFF8000 ) | ((b -> mantissa2 << 17 ) & 0x000007FFF );
104+ ld .ieee .exponent = b -> exponent ;
105+ ld .ieee .negative = b -> negative ;
106+ MEMCPY ( to , & ld , sizeof (long double ));
107+ }
108+ #endif
109+ } else if (!(opal_local_arch & OPAL_ARCH_LDISINTEL ) && (remoteArch & OPAL_ARCH_LDISINTEL )) {
110+ #ifdef __sparcv9
111+ for (i = 0 ; i < count ; i ++ , to ++ ) {
112+ union ieee854_long_double ld ;
113+ struct bit80 * b = (struct bit80 * )to ;
114+ ld .ieee .mantissa3 = 0 ;
115+ ld .ieee .mantissa2 = 0 ;
116+ ld .ieee .mantissa0 = (b -> mantissa0 << 1 ) | (b -> mantissa1 & 0x80000000 );
117+ ld .ieee .mantissa1 = (b -> mantissa1 << 1 ) & 0xFFFFFFFE ;
118+ ld .ieee .exponent = b -> exponent ;
119+ ld .ieee .negative = b -> negative ;
120+ MEMCPY ( to , & ld , sizeof (long double ));
121+ }
122+ #endif
123+ }
124+ #else
125+ assert (0 );
126+ #endif
127+ }
128+ #else
129+ #define opal_dt_swap_long_double (to_p , from_p , size , count , remoteArch )
130+ #endif
131+
65132/**
66133 * BEWARE: Do not use the following macro with composed types such as
67134 * complex. As the swap is done using the entire type sizeof, the
68135 * wrong endianess translation will be done. Instead, use the
69136 * COPY_2SAMETYPE_HETEROGENEOUS.
70137 */
71138#define COPY_TYPE_HETEROGENEOUS ( TYPENAME , TYPE ) \
139+ COPY_TYPE_HETEROGENEOUS_INTERNAL( TYPENAME, TYPE, 0 )
140+
141+ #define COPY_TYPE_HETEROGENEOUS_INTERNAL ( TYPENAME , TYPE , LONG_DOUBLE ) \
72142static int32_t \
73143copy_##TYPENAME##_heterogeneous(opal_convertor_t *pConvertor, uint32_t count, \
74144 const char* from, size_t from_len, ptrdiff_t from_extent, \
@@ -85,9 +155,15 @@ copy_##TYPENAME##_heterogeneous(opal_convertor_t *pConvertor, uint32_t count,
85155 (opal_local_arch & OPAL_ARCH_ISBIGENDIAN)) { \
86156 if( (to_extent == from_extent) && (to_extent == sizeof(TYPE)) ) { \
87157 opal_dt_swap_bytes(to, from, sizeof(TYPE), count); \
158+ if (LONG_DOUBLE) { \
159+ opal_dt_swap_long_double(to, from, sizeof(TYPE), count, pConvertor->remoteArch);\
160+ } \
88161 } else { \
89162 for( i = 0; i < count; i++ ) { \
90163 opal_dt_swap_bytes(to, from, sizeof(TYPE), 1); \
164+ if (LONG_DOUBLE) { \
165+ opal_dt_swap_long_double(to, from, sizeof(TYPE), 1, pConvertor->remoteArch);\
166+ } \
91167 to += to_extent; \
92168 from += from_extent; \
93169 } \
@@ -108,6 +184,9 @@ copy_##TYPENAME##_heterogeneous(opal_convertor_t *pConvertor, uint32_t count,
108184}
109185
110186#define COPY_2SAMETYPE_HETEROGENEOUS ( TYPENAME , TYPE ) \
187+ COPY_2SAMETYPE_HETEROGENEOUS_INTERNAL( TYPENAME, TYPE, 0)
188+
189+ #define COPY_2SAMETYPE_HETEROGENEOUS_INTERNAL ( TYPENAME , TYPE , LONG_DOUBLE ) \
111190static int32_t \
112191copy_##TYPENAME##_heterogeneous(opal_convertor_t *pConvertor, uint32_t count, \
113192 const char* from, size_t from_len, ptrdiff_t from_extent, \
@@ -122,11 +201,17 @@ copy_##TYPENAME##_heterogeneous(opal_convertor_t *pConvertor, uint32_t count,
122201 \
123202 if ((pConvertor->remoteArch & OPAL_ARCH_ISBIGENDIAN) != \
124203 (opal_local_arch & OPAL_ARCH_ISBIGENDIAN)) { \
125- if( (to_extent == from_extent) && (to_extent == sizeof(TYPE)) ) { \
204+ if( (to_extent == from_extent) && (to_extent == (2 * sizeof(TYPE) )) ) { \
126205 opal_dt_swap_bytes(to, from, sizeof(TYPE), 2 * count); \
206+ if (LONG_DOUBLE) { \
207+ opal_dt_swap_long_double(to, from, sizeof(TYPE), 2*count, pConvertor->remoteArch);\
208+ } \
127209 } else { \
128210 for( i = 0; i < count; i++ ) { \
129211 opal_dt_swap_bytes(to, from, sizeof(TYPE), 2); \
212+ if (LONG_DOUBLE) { \
213+ opal_dt_swap_long_double(to, from, sizeof(TYPE), 2, pConvertor->remoteArch);\
214+ } \
130215 to += to_extent; \
131216 from += from_extent; \
132217 } \
@@ -333,7 +418,7 @@ COPY_TYPE_HETEROGENEOUS( float16, float )
333418#elif SIZEOF_DOUBLE == 16
334419COPY_TYPE_HETEROGENEOUS ( float16 , double )
335420#elif HAVE_LONG_DOUBLE && SIZEOF_LONG_DOUBLE == 16
336- COPY_TYPE_HETEROGENEOUS ( float16 , long double )
421+ COPY_TYPE_HETEROGENEOUS_INTERNAL ( float16 , long double , 1 )
337422#else
338423/* #error No basic type for copy function for opal_datatype_float16 found */
339424#define copy_float16_heterogeneous NULL
@@ -354,7 +439,7 @@ COPY_2SAMETYPE_HETEROGENEOUS( double_complex, double )
354439#endif
355440
356441#if HAVE_LONG_DOUBLE__COMPLEX
357- COPY_2SAMETYPE_HETEROGENEOUS ( long_double_complex , long double )
442+ COPY_2SAMETYPE_HETEROGENEOUS_INTERNAL ( long_double_complex , long double , 1 )
358443#else
359444/* #error No basic type for copy function for opal_datatype_long_double_complex found */
360445#define copy_long_double_complex_heterogeneous NULL
0 commit comments