#include "ace/CDR_Base.h"#include "ace/Message_Block.h"#include "ace/OS_Memory.h"#include "ace/OS_NS_string.h"
Go to the source code of this file.
Functions | |
| ACE_RCSID (ace, CDR_Base,"$Id: CDR_Base.cpp 86825 2009-09-28 17:45:23Z johnnyw $") 1void ACE_CDR | |
| ACE_RCSID | ( | ace | , | |
| CDR_Base | , | |||
| "$Id: CDR_Base.cpp 86825 2009-09-28 17:45:23Z johnnyw $" | ||||
| ) |
Definition at line 11 of file CDR_Base.cpp.
00013 : CDR_Base.cpp 86825 2009-09-28 17:45:23Z johnnyw $") 00014 00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00016 00017 #if defined (NONNATIVE_LONGDOUBLE) 00018 static const ACE_INT16 max_eleven_bit = 0x3ff; 00019 static const ACE_INT16 max_fifteen_bit = 0x3fff; 00020 #endif /* NONNATIVE_LONGDOUBLE */ 00021 00022 // 00023 // See comments in CDR_Base.inl about optimization cases for swap_XX_array. 00024 // 00025 00026 void 00027 ACE_CDR::swap_2_array (char const * orig, char* target, size_t n) 00028 { 00029 // ACE_ASSERT(n > 0); The caller checks that n > 0 00030 00031 // We pretend that AMD64/GNU G++ systems have a Pentium CPU to 00032 // take advantage of the inline assembly implementation. 00033 00034 // Later, we try to read in 32 or 64 bit chunks, 00035 // so make sure we don't do that for unaligned addresses. 00036 #if ACE_SIZEOF_LONG == 8 && \ 00037 !((defined(__amd64__) || defined (__x86_64__)) && defined(__GNUG__)) 00038 char const * const o8 = ACE_ptr_align_binary (orig, 8); 00039 while (orig < o8 && n > 0) 00040 { 00041 ACE_CDR::swap_2 (orig, target); 00042 orig += 2; 00043 target += 2; 00044 --n; 00045 } 00046 #else 00047 char const * const o4 = ACE_ptr_align_binary (orig, 4); 00048 // this is an _if_, not a _while_. The mistmatch can only be by 2. 00049 if (orig != o4) 00050 { 00051 ACE_CDR::swap_2 (orig, target); 00052 orig += 2; 00053 target += 2; 00054 --n; 00055 } 00056 #endif 00057 if (n == 0) 00058 return; 00059 00060 // 00061 // Loop unrolling. Here be dragons. 00062 // 00063 00064 // (n & (~3)) is the greatest multiple of 4 not bigger than n. 00065 // In the while loop ahead, orig will move over the array by 8 byte 00066 // increments (4 elements of 2 bytes). 00067 // end marks our barrier for not falling outside. 00068 char const * const end = orig + 2 * (n & (~3)); 00069 00070 // See if we're aligned for writting in 64 or 32 bit chunks... 00071 #if ACE_SIZEOF_LONG == 8 && \ 00072 !((defined(__amd64__) || defined (__x86_64__)) && defined(__GNUG__)) 00073 if (target == ACE_ptr_align_binary (target, 8)) 00074 #else 00075 if (target == ACE_ptr_align_binary (target, 4)) 00076 #endif 00077 { 00078 while (orig < end) 00079 { 00080 #if defined (ACE_HAS_INTEL_ASSEMBLY) 00081 unsigned int a = 00082 * reinterpret_cast<const unsigned int*> (orig); 00083 unsigned int b = 00084 * reinterpret_cast<const unsigned int*> (orig + 4); 00085 asm ( "bswap %1" : "=r" (a) : "0" (a) ); 00086 asm ( "bswap %1" : "=r" (b) : "0" (b) ); 00087 asm ( "rol $16, %1" : "=r" (a) : "0" (a) ); 00088 asm ( "rol $16, %1" : "=r" (b) : "0" (b) ); 00089 * reinterpret_cast<unsigned int*> (target) = a; 00090 * reinterpret_cast<unsigned int*> (target + 4) = b; 00091 #elif defined(ACE_HAS_PENTIUM) \ 00092 && (defined(_MSC_VER) || defined(__BORLANDC__)) \ 00093 && !defined(ACE_LACKS_INLINE_ASSEMBLY) 00094 __asm mov ecx, orig; 00095 __asm mov edx, target; 00096 __asm mov eax, [ecx]; 00097 __asm mov ebx, 4[ecx]; 00098 __asm bswap eax; 00099 __asm bswap ebx; 00100 __asm rol eax, 16; 00101 __asm rol ebx, 16; 00102 __asm mov [edx], eax; 00103 __asm mov 4[edx], ebx; 00104 #elif ACE_SIZEOF_LONG == 8 00105 // 64 bit architecture. 00106 register unsigned long a = 00107 * reinterpret_cast<const unsigned long*> (orig); 00108 00109 register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8; 00110 register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8; 00111 00112 a = (a1 | a2); 00113 00114 * reinterpret_cast<unsigned long*> (target) = a; 00115 #else 00116 register ACE_UINT32 a = 00117 * reinterpret_cast<const ACE_UINT32*> (orig); 00118 register ACE_UINT32 b = 00119 * reinterpret_cast<const ACE_UINT32*> (orig + 4); 00120 00121 register ACE_UINT32 a1 = (a & 0x00ff00ffU) << 8; 00122 register ACE_UINT32 b1 = (b & 0x00ff00ffU) << 8; 00123 register ACE_UINT32 a2 = (a & 0xff00ff00U) >> 8; 00124 register ACE_UINT32 b2 = (b & 0xff00ff00U) >> 8; 00125 00126 a = (a1 | a2); 00127 b = (b1 | b2); 00128 00129 * reinterpret_cast<ACE_UINT32*> (target) = a; 00130 * reinterpret_cast<ACE_UINT32*> (target + 4) = b; 00131 #endif 00132 orig += 8; 00133 target += 8; 00134 } 00135 } 00136 else 00137 { 00138 // We're out of luck. We have to write in 2 byte chunks. 00139 while (orig < end) 00140 { 00141 #if defined (ACE_HAS_INTEL_ASSEMBLY) 00142 unsigned int a = 00143 * reinterpret_cast<const unsigned int*> (orig); 00144 unsigned int b = 00145 * reinterpret_cast<const unsigned int*> (orig + 4); 00146 asm ( "bswap %1" : "=r" (a) : "0" (a) ); 00147 asm ( "bswap %1" : "=r" (b) : "0" (b) ); 00148 // We're little endian. 00149 * reinterpret_cast<unsigned short*> (target + 2) 00150 = (unsigned short) (a & 0xffff); 00151 * reinterpret_cast<unsigned short*> (target + 6) 00152 = (unsigned short) (b & 0xffff); 00153 asm ( "shrl $16, %1" : "=r" (a) : "0" (a) ); 00154 asm ( "shrl $16, %1" : "=r" (b) : "0" (b) ); 00155 * reinterpret_cast<unsigned short*> (target + 0) 00156 = (unsigned short) (a & 0xffff); 00157 * reinterpret_cast<unsigned short*> (target + 4) 00158 = (unsigned short) (b & 0xffff); 00159 #elif defined (ACE_HAS_PENTIUM) \ 00160 && (defined (_MSC_VER) || defined (__BORLANDC__)) \ 00161 && !defined (ACE_LACKS_INLINE_ASSEMBLY) 00162 __asm mov ecx, orig; 00163 __asm mov edx, target; 00164 __asm mov eax, [ecx]; 00165 __asm mov ebx, 4[ecx]; 00166 __asm bswap eax; 00167 __asm bswap ebx; 00168 // We're little endian. 00169 __asm mov 2[edx], ax; 00170 __asm mov 6[edx], bx; 00171 __asm shr eax, 16; 00172 __asm shr ebx, 16; 00173 __asm mov 0[edx], ax; 00174 __asm mov 4[edx], bx; 00175 #elif ACE_SIZEOF_LONG == 8 00176 // 64 bit architecture. 00177 register unsigned long a = 00178 * reinterpret_cast<const unsigned long*> (orig); 00179 00180 register unsigned long a1 = (a & 0x00ff00ff00ff00ffUL) << 8; 00181 register unsigned long a2 = (a & 0xff00ff00ff00ff00UL) >> 8; 00182 00183 a = (a1 | a2); 00184 00185 ACE_UINT16 b1 = static_cast<ACE_UINT16> (a >> 48); 00186 ACE_UINT16 b2 = static_cast<ACE_UINT16> ((a >> 32) & 0xffff); 00187 ACE_UINT16 b3 = static_cast<ACE_UINT16> ((a >> 16) & 0xffff); 00188 ACE_UINT16 b4 = static_cast<ACE_UINT16> (a & 0xffff); 00189 00190 #if defined(ACE_LITTLE_ENDIAN) 00191 * reinterpret_cast<ACE_UINT16*> (target) = b4; 00192 * reinterpret_cast<ACE_UINT16*> (target + 2) = b3; 00193 * reinterpret_cast<ACE_UINT16*> (target + 4) = b2; 00194 * reinterpret_cast<ACE_UINT16*> (target + 6) = b1; 00195 #else 00196 * reinterpret_cast<ACE_UINT16*> (target) = b1; 00197 * reinterpret_cast<ACE_UINT16*> (target + 2) = b2; 00198 * reinterpret_cast<ACE_UINT16*> (target + 4) = b3; 00199 * reinterpret_cast<ACE_UINT16*> (target + 6) = b4; 00200 #endif 00201 #else 00202 register ACE_UINT32 a = 00203 * reinterpret_cast<const ACE_UINT32*> (orig); 00204 register ACE_UINT32 b = 00205 * reinterpret_cast<const ACE_UINT32*> (orig + 4); 00206 00207 register ACE_UINT32 a1 = (a & 0x00ff00ff) << 8; 00208 register ACE_UINT32 b1 = (b & 0x00ff00ff) << 8; 00209 register ACE_UINT32 a2 = (a & 0xff00ff00) >> 8; 00210 register ACE_UINT32 b2 = (b & 0xff00ff00) >> 8; 00211 00212 a = (a1 | a2); 00213 b = (b1 | b2); 00214 00215 ACE_UINT32 c1 = static_cast<ACE_UINT16> (a >> 16); 00216 ACE_UINT32 c2 = static_cast<ACE_UINT16> (a & 0xffff); 00217 ACE_UINT32 c3 = static_cast<ACE_UINT16> (b >> 16); 00218 ACE_UINT32 c4 = static_cast<ACE_UINT16> (b & 0xffff); 00219 00220 #if defined(ACE_LITTLE_ENDIAN) 00221 * reinterpret_cast<ACE_UINT16*> (target) = c2; 00222 * reinterpret_cast<ACE_UINT16*> (target + 2) = c1; 00223 * reinterpret_cast<ACE_UINT16*> (target + 4) = c4; 00224 * reinterpret_cast<ACE_UINT16*> (target + 6) = c3; 00225 #else 00226 * reinterpret_cast<ACE_UINT16*> (target) = c1; 00227 * reinterpret_cast<ACE_UINT16*> (target + 2) = c2; 00228 * reinterpret_cast<ACE_UINT16*> (target + 4) = c3; 00229 * reinterpret_cast<ACE_UINT16*> (target + 6) = c4; 00230 #endif 00231 #endif 00232 00233 orig += 8; 00234 target += 8; 00235 } 00236 } 00237 00238 // (n & 3) == (n % 4). 00239 switch (n&3) { 00240 case 3: 00241 ACE_CDR::swap_2 (orig, target); 00242 orig += 2; 00243 target += 2; 00244 case 2: 00245 ACE_CDR::swap_2 (orig, target); 00246 orig += 2; 00247 target += 2; 00248 case 1: 00249 ACE_CDR::swap_2 (orig, target); 00250 } 00251 }
1.6.1