2 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
3 // Take advantage of MSVC++ byte swapping compiler intrinsics (found
5 # pragma intrinsic (_byteswap_ushort, _byteswap_ulong, _byteswap_uint64)
6 #endif /* ACE_HAS_INTRINSIC_BYTESWAP */
8 #if defined (ACE_HAS_BSWAP_16) || defined (ACE_HAS_BSWAP_32) || defined (ACE_HAS_BSWAP_64)
9 # include "ace/os_include/os_byteswap.h"
12 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
15 // The ACE_CDR::swap_X and ACE_CDR::swap_X_array routines are broken
16 // in 5 cases for optimization:
18 // * MSVC++ 7.1 or better
19 // => Compiler intrinsics
21 // * AMD64 CPU + gnu g++
22 // => gcc amd64 inline assembly.
24 // * x86 Pentium CPU + gnu g++
25 // (ACE_HAS_PENTIUM && __GNUG__)
26 // => gcc x86 inline assembly.
28 // * x86 Pentium CPU and (_MSC_VER) or BORLAND C++)
29 // (ACE_HAS_PENTIUM && ( _MSC_VER || __BORLANDC__ )
30 // => MSC x86 inline assembly.
32 // * 64 bit architecture
33 // (ACE_SIZEOF_LONG == 8)
34 // => shift/masks using 64bit words.
37 // (none of the above)
38 // => shift/masks using 32bit words.
40 // Some things you could find useful to know if you intend to mess
41 // with this optimizations for swaps:
43 // * MSVC++ don't assume register values are conserved between
44 // statements. So you can clobber any register you want,
45 // whenever you want (well not *anyone* really, see manual).
46 // The MSVC++ optimizer will try to pick different registers
47 // for the C++ statements sorrounding your asm block, and if
48 // it's not possible will use the stack.
50 // * If you clobber registers with asm statements in gcc, you
51 // better do it in an asm-only function, or save/restore them
52 // before/after in the stack. If not, sorrounding C statements
53 // could end using the same registers and big-badda-bum (been
54 // there, done that...). The big-badda-bum could happen *even
55 // if you specify the clobbered register in your asm's*.
56 // Even better, use gcc asm syntax for detecting the register
57 // asigned to a certain variable so you don't have to clobber any
62 ACE_CDR::swap_2 (const char *orig, char* target)
64 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
65 // Take advantage of MSVC++ compiler intrinsic byte swapping
67 *reinterpret_cast<unsigned short *> (target) =
68 _byteswap_ushort (*reinterpret_cast<unsigned short const *> (orig));
69 #elif defined (ACE_HAS_BUILTIN_BSWAP16)
70 *reinterpret_cast<uint16_t *> (target) =
71 __builtin_bswap16 (*reinterpret_cast<uint16_t const *> (orig));
72 #elif defined (ACE_HAS_BSWAP16)
73 *reinterpret_cast<uint16_t *> (target) =
74 bswap16 (*reinterpret_cast<uint16_t const *> (orig));
75 #elif defined (ACE_HAS_BSWAP_16)
76 *reinterpret_cast<uint16_t *> (target) =
77 bswap_16 (*reinterpret_cast<uint16_t const *> (orig));
78 #elif defined(ACE_HAS_INTEL_ASSEMBLY)
80 *reinterpret_cast<const unsigned short*> (orig);
81 asm( "rolw $8, %0" : "=r" (a) : "0" (a) );
82 *reinterpret_cast<unsigned short*> (target) = a;
83 #elif defined (ACE_HAS_PENTIUM) \
84 && (defined(_MSC_VER) || defined(__BORLANDC__)) \
85 && !defined(ACE_LACKS_INLINE_ASSEMBLY)
87 __asm mov ecx, target;
92 ACE_UINT16 usrc = * reinterpret_cast<const ACE_UINT16*> (orig);
93 ACE_UINT16* udst = reinterpret_cast<ACE_UINT16*> (target);
94 *udst = (usrc << 8) | (usrc >> 8);
95 #endif /* ACE_HAS_PENTIUM */
99 ACE_CDR::swap_4 (const char* orig, char* target)
101 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
102 // Take advantage of MSVC++ compiler intrinsic byte swapping
104 *reinterpret_cast<unsigned long *> (target) =
105 _byteswap_ulong (*reinterpret_cast<unsigned long const *> (orig));
106 #elif defined (ACE_HAS_BUILTIN_BSWAP32)
107 *reinterpret_cast<uint32_t *> (target) =
108 __builtin_bswap32 (*reinterpret_cast<uint32_t const *> (orig));
109 #elif defined (ACE_HAS_BSWAP32)
110 *reinterpret_cast<uint32_t *> (target) =
111 bswap32 (*reinterpret_cast<uint32_t const *> (orig));
112 #elif defined (ACE_HAS_BSWAP_32)
113 *reinterpret_cast<uint32_t *> (target) =
114 bswap_32 (*reinterpret_cast<uint32_t const *> (orig));
115 #elif defined(ACE_HAS_INTEL_ASSEMBLY)
116 // We have ACE_HAS_PENTIUM, so we know the sizeof's.
118 *reinterpret_cast<const unsigned int*> (orig);
119 asm ("bswap %1" : "=r" (j) : "0" (j));
120 *reinterpret_cast<unsigned int*> (target) = j;
121 #elif defined(ACE_HAS_PENTIUM) \
122 && (defined(_MSC_VER) || defined(__BORLANDC__)) \
123 && !defined(ACE_LACKS_INLINE_ASSEMBLY)
125 __asm mov ecx, target;
126 __asm mov eax, [ebx];
128 __asm mov [ecx], eax;
130 ACE_UINT32 x = * reinterpret_cast<const ACE_UINT32*> (orig);
131 x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
132 * reinterpret_cast<ACE_UINT32*> (target) = x;
133 #endif /* ACE_HAS_INTRINSIC_BYTESWAP */
137 ACE_CDR::swap_8 (const char* orig, char* target)
139 #if defined (ACE_HAS_INTRINSIC_BYTESWAP)
140 // Take advantage of MSVC++ compiler intrinsic byte swapping
142 *reinterpret_cast<unsigned __int64 *> (target) =
143 _byteswap_uint64 (*reinterpret_cast<unsigned __int64 const *> (orig));
144 #elif defined (ACE_HAS_BUILTIN_BSWAP64)
145 *reinterpret_cast<uint64_t *> (target) =
146 __builtin_bswap64 (*reinterpret_cast<uint64_t const *> (orig));
147 #elif defined (ACE_HAS_BSWAP64)
148 *reinterpret_cast<uint64_t *> (target) =
149 bswap64 (*reinterpret_cast<uint64_t const *> (orig));
150 #elif defined (ACE_HAS_BSWAP_64)
151 *reinterpret_cast<uint64_t *> (target) =
152 bswap_64 (*reinterpret_cast<uint64_t const *> (orig));
153 #elif (defined (__amd64__) || defined (__x86_64__)) && defined(__GNUG__) \
154 && !defined(ACE_LACKS_INLINE_ASSEMBLY)
156 * reinterpret_cast<const unsigned long*> (orig);
157 asm ("bswapq %1" : "=r" (x) : "0" (x));
158 *reinterpret_cast<unsigned long*> (target) = x;
159 #elif defined(ACE_HAS_PENTIUM) && defined(__GNUG__) \
160 && !defined(ACE_LACKS_INLINE_ASSEMBLY)
161 unsigned int i =*reinterpret_cast<const unsigned int*> (orig);
162 unsigned int j = *reinterpret_cast<const unsigned int*> (orig + 4);
163 asm ("bswap %1" : "=r" (i) : "0" (i));
164 asm ("bswap %1" : "=r" (j) : "0" (j));
165 *reinterpret_cast<unsigned int*> (target + 4) = i;
166 *reinterpret_cast<unsigned int*> (target) = j;
167 #elif defined(ACE_HAS_PENTIUM) \
168 && (defined(_MSC_VER) || defined(__BORLANDC__)) \
169 && !defined(ACE_LACKS_INLINE_ASSEMBLY)
171 __asm mov edx, target;
172 __asm mov eax, [ecx];
173 __asm mov ebx, 4[ecx];
176 __asm mov 4[edx], eax;
177 __asm mov [edx], ebx;
178 #elif ACE_SIZEOF_LONG == 8
179 // 64 bit architecture.
180 unsigned long x = * reinterpret_cast<const unsigned long*> (orig);
181 unsigned long x84 = (x & 0x000000ff000000ffUL) << 24;
182 unsigned long x73 = (x & 0x0000ff000000ff00UL) << 8;
183 unsigned long x62 = (x & 0x00ff000000ff0000UL) >> 8;
184 unsigned long x51 = (x & 0xff000000ff000000UL) >> 24;
185 x = (x84 | x73 | x62 | x51);
186 x = (x << 32) | (x >> 32);
187 *reinterpret_cast<unsigned long*> (target) = x;
189 ACE_UINT32 x = * reinterpret_cast<const ACE_UINT32*> (orig);
190 ACE_UINT32 y = * reinterpret_cast<const ACE_UINT32*> (orig + 4);
191 x = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
192 y = (y << 24) | ((y & 0xff00) << 8) | ((y & 0xff0000) >> 8) | (y >> 24);
193 * reinterpret_cast<ACE_UINT32*> (target) = y;
194 * reinterpret_cast<ACE_UINT32*> (target + 4) = x;
195 #endif /* ACE_HAS_INTRINSIC_BYTESWAP */
199 ACE_CDR::swap_16 (const char* orig, char* target)
201 swap_8 (orig + 8, target);
202 swap_8 (orig, target + 8);
206 ACE_CDR::first_size (size_t minsize)
209 return ACE_CDR::DEFAULT_BUFSIZE;
211 size_t newsize = ACE_CDR::DEFAULT_BUFSIZE;
212 while (newsize < minsize)
214 if (newsize < ACE_CDR::EXP_GROWTH_MAX)
216 // We grow exponentially at the beginning, this is fast and
217 // reduces the number of allocations.
219 // Quickly multiply by two using a bit shift. This is
220 // guaranteed to work since the variable is an unsigned
226 // but continuing with exponential growth can result in over
227 // allocations and easily yield an allocation failure.
228 // So we grow linearly when the buffer is too big.
229 newsize += ACE_CDR::LINEAR_GROWTH_CHUNK;
236 ACE_CDR::next_size (size_t minsize)
238 size_t newsize = ACE_CDR::first_size (minsize);
240 if (newsize == minsize)
242 // If necessary increment the size
243 if (newsize < ACE_CDR::EXP_GROWTH_MAX)
244 // Quickly multiply by two using a bit shift. This is
245 // guaranteed to work since the variable is an unsigned
249 newsize += ACE_CDR::LINEAR_GROWTH_CHUNK;
255 ACE_INLINE ACE_CDR::UShort
256 ACE_CDR::Fixed::fixed_digits () const
258 return this->digits_;
261 ACE_INLINE ACE_CDR::UShort
262 ACE_CDR::Fixed::fixed_scale () const
268 ACE_CDR::Fixed::sign () const
270 return (this->value_[15] & 0xf) == NEGATIVE;
273 ACE_INLINE ACE_CDR::Octet
274 ACE_CDR::Fixed::digit (int n) const
276 const Octet x = this->value_[15 - (n + 1) / 2];
277 return (n % 2) ? x & 0xf : (x >> 4);
281 ACE_CDR::Fixed::digit (int n, int val)
283 const int idx = 15 - (n + 1) / 2;
284 this->value_[idx] = (n % 2) ? (this->value_[idx] & 0xf0) | val
285 : ((val << 4) | (this->value_[idx] & 0xf));
289 ACE_CDR::Fixed::Proxy::Proxy (bool high_nibble, Octet &element)
290 : high_nibble_ (high_nibble), element_ (element) {}
292 ACE_INLINE ACE_CDR::Fixed::Proxy &
293 ACE_CDR::Fixed::Proxy::operator= (Octet val)
295 this->element_ = this->high_nibble_
296 ? (val << 4) | (this->element_ & 0xf)
297 : ((this->element_ & 0xf0) | val);
301 ACE_INLINE ACE_CDR::Fixed::Proxy &
302 ACE_CDR::Fixed::Proxy::operator+= (int rhs)
304 const Octet val = static_cast<Octet> (*this + rhs);
308 ACE_INLINE ACE_CDR::Fixed::Proxy &
309 ACE_CDR::Fixed::Proxy::operator-= (int rhs)
311 const Octet val = static_cast<Octet> (*this - rhs);
315 ACE_INLINE ACE_CDR::Fixed::Proxy &
316 ACE_CDR::Fixed::Proxy::operator++ ()
318 const Octet val = static_cast<Octet> (*this) + 1;
322 ACE_INLINE ACE_CDR::Fixed::Proxy &
323 ACE_CDR::Fixed::Proxy::operator-- ()
325 const Octet val = static_cast<Octet>(*this) - 1;
330 ACE_CDR::Fixed::Proxy::operator ACE_CDR::Octet () const
332 return this->high_nibble_ ? this->element_ >> 4 : (this->element_ & 0xf);
336 ACE_CDR::Fixed::IteratorBase::IteratorBase (int digit)
340 ACE_CDR::Fixed::IteratorBase::high_nibble () const
342 return this->digit_ % 2 == 0;
345 ACE_INLINE ACE_CDR::Octet &
346 ACE_CDR::Fixed::IteratorBase::storage (Fixed *outer) const
348 return outer->value_[15 - (this->digit_ + 1) / 2];
351 ACE_INLINE ACE_CDR::Octet
352 ACE_CDR::Fixed::IteratorBase::storage (const Fixed *outer) const
354 return outer->value_[15 - (this->digit_ + 1) / 2];
358 ACE_CDR::Fixed::IteratorBase::compare (const IteratorBase &rhs) const
360 return this->digit_ == rhs.digit_;
364 ACE_CDR::Fixed::Iterator::Iterator (Fixed *outer, int digit)
365 : IteratorBase (digit), outer_ (outer) {}
367 ACE_INLINE ACE_CDR::Fixed::Proxy
368 ACE_CDR::Fixed::Iterator::operator* ()
370 return Proxy (this->high_nibble (), this->storage (this->outer_));
373 ACE_INLINE ACE_CDR::Fixed::Iterator &
374 ACE_CDR::Fixed::Iterator::operator+= (std::ptrdiff_t n)
376 this->digit_ += static_cast<int> (n);
380 ACE_INLINE ACE_CDR::Fixed::Iterator &
381 ACE_CDR::Fixed::Iterator::operator++ ()
387 ACE_INLINE ACE_CDR::Fixed::Iterator
388 ACE_CDR::Fixed::Iterator::operator++ (int)
390 const Iterator cpy (*this);
395 ACE_INLINE ACE_CDR::Fixed::Iterator &
396 ACE_CDR::Fixed::Iterator::operator-- ()
402 ACE_INLINE ACE_CDR::Fixed::Iterator
403 ACE_CDR::Fixed::Iterator::operator-- (int)
405 const Iterator cpy (*this);
411 ACE_CDR::Fixed::Iterator::operator== (const Iterator &rhs) const
413 return this->compare (rhs);
417 ACE_CDR::Fixed::Iterator::operator!= (const Iterator &rhs) const
419 return !(*this == rhs);
423 ACE_CDR::Fixed::ConstIterator::ConstIterator (const Fixed *outer, int digit)
424 : IteratorBase (digit), outer_ (outer) {}
426 ACE_INLINE ACE_CDR::Octet
427 ACE_CDR::Fixed::ConstIterator::operator* ()
429 const Octet storage = this->storage (this->outer_);
430 return this->high_nibble () ? storage >> 4 : (storage & 0xf);
433 ACE_INLINE ACE_CDR::Fixed::ConstIterator &
434 ACE_CDR::Fixed::ConstIterator::operator+= (std::ptrdiff_t n)
436 this->digit_ += static_cast<int> (n);
440 ACE_INLINE ACE_CDR::Fixed::ConstIterator &
441 ACE_CDR::Fixed::ConstIterator::operator++ ()
447 ACE_INLINE ACE_CDR::Fixed::ConstIterator
448 ACE_CDR::Fixed::ConstIterator::operator++ (int)
450 const ConstIterator cpy (*this);
455 ACE_INLINE ACE_CDR::Fixed::ConstIterator &
456 ACE_CDR::Fixed::ConstIterator::operator-- ()
462 ACE_INLINE ACE_CDR::Fixed::ConstIterator
463 ACE_CDR::Fixed::ConstIterator::operator-- (int)
465 const ConstIterator cpy (*this);
471 ACE_CDR::Fixed::ConstIterator::operator== (const ConstIterator &rhs) const
473 return this->compare (rhs);
477 ACE_CDR::Fixed::ConstIterator::operator!= (const ConstIterator &rhs) const
479 return !(*this == rhs);
482 ACE_INLINE ACE_CDR::Fixed::Iterator
483 ACE_CDR::Fixed::begin ()
485 return Iterator (this);
488 ACE_INLINE ACE_CDR::Fixed::ConstIterator
489 ACE_CDR::Fixed::begin () const
491 return ConstIterator (this);
494 ACE_INLINE ACE_CDR::Fixed::ConstIterator
495 ACE_CDR::Fixed::cbegin () const
497 return ConstIterator (this);
500 ACE_INLINE ACE_CDR::Fixed::Iterator
501 ACE_CDR::Fixed::end ()
503 return Iterator (this, this->digits_);
506 ACE_INLINE ACE_CDR::Fixed::ConstIterator
507 ACE_CDR::Fixed::end () const
509 return ConstIterator (this, this->digits_);
512 ACE_INLINE ACE_CDR::Fixed::ConstIterator
513 ACE_CDR::Fixed::cend () const
515 return ConstIterator (this, this->digits_);
518 ACE_INLINE ACE_CDR::Fixed
519 ACE_CDR::Fixed::operator++ (int)
521 const Fixed cpy (*this);
526 ACE_INLINE ACE_CDR::Fixed
527 ACE_CDR::Fixed::operator-- (int)
529 const Fixed cpy (*this);
534 ACE_INLINE ACE_CDR::Fixed
535 ACE_CDR::Fixed::operator+ () const
540 ACE_INLINE ACE_CDR::Fixed
541 ACE_CDR::Fixed::operator- () const
544 f.value_[15] = (f.value_[15] & 0xf0) | (f.sign () ? POSITIVE : NEGATIVE);
549 ACE_CDR::Fixed::ltrim ()
551 for (int i = this->digits_ - 1; i >= this->scale_ && i > 0; --i)
552 if (this->digit (i) == 0)
558 ACE_INLINE ACE_CDR::Fixed
559 operator+ (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
561 ACE_CDR::Fixed f = lhs;
566 ACE_INLINE ACE_CDR::Fixed
567 operator- (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
569 ACE_CDR::Fixed f = lhs;
574 ACE_INLINE ACE_CDR::Fixed
575 operator* (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
577 ACE_CDR::Fixed f = lhs;
582 ACE_INLINE ACE_CDR::Fixed
583 operator/ (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
585 ACE_CDR::Fixed f = lhs;
591 operator< (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
593 return lhs.less (rhs);
597 operator> (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
603 operator>= (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
609 operator<= (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
615 operator== (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
617 return lhs.equal (rhs);
621 operator!= (const ACE_CDR::Fixed &lhs, const ACE_CDR::Fixed &rhs)
623 return !(lhs == rhs);
627 ACE_END_VERSIONED_NAMESPACE_DECL
629 // ****************************************************************