CDR_Base.cpp File Reference

#include "ace/CDR_Base.h"
#include "ace/Message_Block.h"
#include "ace/OS_Memory.h"
#include "ace/OS_NS_string.h"
Include dependency graph for CDR_Base.cpp:

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

Function Documentation

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 }

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Sun Nov 22 23:10:01 2009 for ACE by  doxygen 1.6.1