summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelliott_c <ocielliottc@users.noreply.github.com>2007-01-31 19:04:39 +0000
committerelliott_c <ocielliottc@users.noreply.github.com>2007-01-31 19:04:39 +0000
commit8110441969cc430b1237a4027aeeecb30cba4801 (patch)
treeb8760292b42947418b364d03203a090fb7407828
parent05b470b47454fd37d6ff806d18bbc3e1ea7a0375 (diff)
downloadATCD-8110441969cc430b1237a4027aeeecb30cba4801.tar.gz
ChangeLogTag: Wed Jan 31 19:03:37 UTC 2007 Chad Elliott <elliott_c@ociweb.com>
-rw-r--r--ACE/ChangeLog28
-rw-r--r--ACE/ace/Basic_Types.h2
-rw-r--r--ACE/ace/CDR_Base.cpp160
-rw-r--r--ACE/ace/CDR_Base.h53
-rw-r--r--ACE/bin/tao_orb_tests.lst1
5 files changed, 243 insertions, 1 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog
index f5d6a7f3f42..2540adbaf9c 100644
--- a/ACE/ChangeLog
+++ b/ACE/ChangeLog
@@ -1,3 +1,31 @@
+Wed Jan 31 19:03:37 UTC 2007 Chad Elliott <elliott_c@ociweb.com>
+
+ * ace/Basic_Types.h:
+
+ Added constants ACE_FLT_MIN and ACE_DBL_MIN to provide consistency
+ with ACE_FLT_MAX AND ACE_DBL_MAX.
+
+ * ace/CDR_Base.h:
+ * ace/CDR_Base.cpp:
+
+ Enhanced the ACE_CDR::LongDouble class which is used on platforms
+ where the native long double is not 16 bytes.
+
+ Provided operators to support multiplication, division, addition
+ and subtraction as well as conversion to the native long double.
+
+ An assign() method is also provided to set the value of the
+ ACE_CDR::LongDouble. Since this class will be stored in a union
+ (if used as an IDL type), it can not have a non-trivial constructor
+ or assignment operator. The existing
+ ACE_CDR_LONG_DOUBLE_INITIALIZER macro is used to initialize the
+ LongDouble and a new macro, ACE_CDR_LONG_DOUBLE_ASSIGNMENT, is
+ used to assign to the LongDouble in a portable fashion.
+
+ * bin/tao_orb_tests.lst:
+
+ Added the new TAO LongDouble test.
+
Wed Jan 31 17:30:46 UTC 2007 Steve Huston <shuston@riverace.com>
* ace/config-hpux-11.00.h:
diff --git a/ACE/ace/Basic_Types.h b/ACE/ace/Basic_Types.h
index 48a0becdb12..ec2ca3cc2ad 100644
--- a/ACE/ace/Basic_Types.h
+++ b/ACE/ace/Basic_Types.h
@@ -839,7 +839,9 @@ ACE_END_VERSIONED_NAMESPACE_DECL
#define ACE_UINT64_MAX ACE_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF)
// These use ANSI/IEEE format.
#define ACE_FLT_MAX 3.402823466e+38F
+#define ACE_FLT_MIN 1.175494351e-38F
#define ACE_DBL_MAX 1.7976931348623158e+308
+#define ACE_DBL_MIN 2.2250738585072014e-308
# if defined (__ACE_INLINE__)
# include "ace/Basic_Types.inl"
diff --git a/ACE/ace/CDR_Base.cpp b/ACE/ace/CDR_Base.cpp
index 8b051985eba..6be30a21b8c 100644
--- a/ACE/ace/CDR_Base.cpp
+++ b/ACE/ace/CDR_Base.cpp
@@ -14,6 +14,11 @@ ACE_RCSID (ace,
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+#if defined (NONNATIVE_LONGDOUBLE)
+static const ACE_INT16 max_eleven_bit = 0x3ff;
+static const ACE_INT16 max_fifteen_bit = 0x3fff;
+#endif /* NONNATIVE_LONGDOUBLE */
+
//
// See comments in CDR_Base.inl about optimization cases for swap_XX_array.
//
@@ -599,6 +604,85 @@ ACE_CDR::LongLong::operator!= (const ACE_CDR::LongLong &rhs) const
#endif /* NONNATIVE_LONGLONG */
#if defined (NONNATIVE_LONGDOUBLE)
+ACE_CDR::LongDouble&
+ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble::NativeImpl& rhs)
+{
+ ACE_OS::memset (this->ld, 0, sizeof (this->ld));
+
+ if (sizeof (rhs) == 8)
+ {
+#if defined (ACE_LITTLE_ENDIAN)
+ static const size_t byte_zero = 1;
+ static const size_t byte_one = 0;
+ char rhs_ptr[16];
+ ACE_CDR::swap_8 (reinterpret_cast<const char*> (&rhs), rhs_ptr);
+#else
+ static const size_t byte_zero = 0;
+ static const size_t byte_one = 1;
+ const char* rhs_ptr = reinterpret_cast<const char*> (&rhs);
+#endif
+ ACE_INT16 sign = static_cast<ACE_INT16> (
+ static_cast<signed char> (rhs_ptr[0])) & 0x8000;
+ ACE_INT16 exponent = ((rhs_ptr[0] & 0x7f) << 4) |
+ ((rhs_ptr[1] >> 4) & 0xf);
+ const char* exp_ptr = reinterpret_cast<const char*> (&exponent);
+
+ // Infinity and NaN have an exponent of 0x7ff in 64-bit IEEE
+ if (exponent == 0x7ff)
+ {
+ exponent = 0x7fff;
+ }
+ else
+ {
+ exponent = (exponent - max_eleven_bit) + max_fifteen_bit;
+ }
+ exponent |= sign;
+
+ // Store the sign bit and exponent
+ this->ld[0] = exp_ptr[byte_zero];
+ this->ld[1] = exp_ptr[byte_one];
+
+ // Store the mantissa. In an 8 byte double, it is split by
+ // 4 bits (because of the 12 bits for sign and exponent), so
+ // we have to shift and or the rhs to get the right bytes.
+ size_t li = 2;
+ bool direction = true;
+ for (size_t ri = 1; ri < sizeof (rhs);)
+ {
+ if (direction)
+ {
+ this->ld[li] |= ((rhs_ptr[ri] << 4) & 0xf0);
+ direction = false;
+ ri++;
+ }
+ else
+ {
+ this->ld[li] |= ((rhs_ptr[ri] >> 4) & 0xf);
+ direction = true;
+ li++;
+ }
+ }
+#if defined (ACE_LITTLE_ENDIAN)
+ ACE_OS::memcpy (rhs_ptr, this->ld, sizeof (this->ld));
+ ACE_CDR::swap_16 (rhs_ptr, this->ld);
+#endif
+ }
+ else
+ {
+ ACE_OS::memcpy(this->ld,
+ reinterpret_cast<const char*> (&rhs), sizeof (rhs));
+ }
+ return *this;
+}
+
+ACE_CDR::LongDouble&
+ACE_CDR::LongDouble::assign (const ACE_CDR::LongDouble& rhs)
+{
+ if (this != &rhs)
+ *this = rhs;
+ return *this;
+}
+
bool
ACE_CDR::LongDouble::operator== (const ACE_CDR::LongDouble &rhs) const
{
@@ -611,6 +695,82 @@ ACE_CDR::LongDouble::operator!= (const ACE_CDR::LongDouble &rhs) const
return ACE_OS::memcmp (this->ld, rhs.ld, 16) != 0;
}
+ACE_CDR::LongDouble::operator ACE_CDR::LongDouble::NativeImpl () const
+{
+ ACE_CDR::LongDouble::NativeImpl ret = 0.0;
+ char* lhs_ptr = reinterpret_cast<char*> (&ret);
+
+ if (sizeof (ret) == 8)
+ {
+#if defined (ACE_LITTLE_ENDIAN)
+ static const size_t byte_zero = 1;
+ static const size_t byte_one = 0;
+ char copy[16];
+ ACE_CDR::swap_16 (this->ld, copy);
+#else
+ static const size_t byte_zero = 0;
+ static const size_t byte_one = 1;
+ const char* copy = this->ld;
+#endif
+ ACE_INT16 exponent = 0;
+ char* exp_ptr = reinterpret_cast<char*> (&exponent);
+ exp_ptr[byte_zero] = copy[0];
+ exp_ptr[byte_one] = copy[1];
+
+ ACE_INT16 sign = (exponent & 0x8000);
+ exponent &= 0x7fff;
+
+ // Infinity and NaN have an exponent of 0x7fff in 128-bit IEEE
+ if (exponent == 0x7fff)
+ {
+ exponent = 0x7ff;
+ }
+ else
+ {
+ exponent = (exponent - max_fifteen_bit) + max_eleven_bit;
+ }
+ exponent = (exponent << 4) | sign;
+
+ // Store the sign and exponent
+ lhs_ptr[0] = exp_ptr[byte_zero];
+ lhs_ptr[1] = exp_ptr[byte_one];
+
+ // Store the mantissa. In an 8 byte double, it is split by
+ // 4 bits (because of the 12 bits for sign and exponent), so
+ // we have to shift and or the rhs to get the right bytes.
+ size_t li = 1;
+ bool direction = true;
+ for (size_t ri = 2; li < sizeof (ret);) {
+ if (direction)
+ {
+ lhs_ptr[li] |= ((copy[ri] >> 4) & 0xf);
+ direction = false;
+ li++;
+ }
+ else
+ {
+ lhs_ptr[li] |= ((copy[ri] & 0xf) << 4);
+ direction = true;
+ ri++;
+ }
+ }
+
+#if defined (ACE_LITTLE_ENDIAN)
+ ACE_CDR::swap_8 (lhs_ptr, lhs_ptr);
+#endif
+ }
+ else
+ {
+ ACE_OS::memcpy(lhs_ptr, this->ld, sizeof (ret));
+ }
+
+ // This bit of code is unnecessary. However, this code is
+ // necessary to work around a bug in the gcc 4.1.1 optimizer.
+ ACE_CDR::LongDouble tmp;
+ tmp.assign (ret);
+
+ return ret;
+}
#endif /* NONNATIVE_LONGDOUBLE */
#if defined(_UNICOS) && !defined(_CRAYMPP)
diff --git a/ACE/ace/CDR_Base.h b/ACE/ace/CDR_Base.h
index 42541504934..3507b21c4ae 100644
--- a/ACE/ace/CDR_Base.h
+++ b/ACE/ace/CDR_Base.h
@@ -267,15 +267,66 @@ public:
# if ACE_SIZEOF_LONG_DOUBLE == 16
typedef long double LongDouble;
# define ACE_CDR_LONG_DOUBLE_INITIALIZER 0
+# define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS) LHS = RHS
# else
# define NONNATIVE_LONGDOUBLE
# define ACE_CDR_LONG_DOUBLE_INITIALIZER {{0}}
+# define ACE_CDR_LONG_DOUBLE_ASSIGNMENT(LHS, RHS) LHS.assign (RHS)
struct ACE_Export LongDouble
{
+ // VxWorks' compiler (gcc 2.96) gets confused by the operator long
+ // double, so we avoid using long double as the NativeImpl.
+ // Linux's x86 long double format (12 or 16 bytes) is incompatible
+ // with Windows, Solaris, AIX, MacOS X and HP-UX (and probably others)
+ // long double format (8 or 16 bytes). If you need 32-bit Linux to
+ // inter-operate with 64-bit Linux you will want to define this
+ // macro so that "long double" is used. Otherwise, do not define
+ // this macro.
+# if defined (ACE_IMPLEMENT_WITH_NATIVE_LONGDOUBLE) || \
+ (!defined (linux) && !defined (VXWORKS))
+ typedef long double NativeImpl;
+# else
+ typedef double NativeImpl;
+# endif /* ACE_IMPLEMENT_WITH_NATIVE_LONGDOUBLE || (!linux && !VXWORKS) */
+
char ld[16];
+
+ LongDouble& assign (const NativeImpl& rhs);
+ LongDouble& assign (const LongDouble& rhs);
+
bool operator== (const LongDouble &rhs) const;
bool operator!= (const LongDouble &rhs) const;
- // @@ also need other comparison operators.
+
+ LongDouble& operator*= (const NativeImpl rhs) {
+ return this->assign (static_cast<NativeImpl> (*this) * rhs);
+ }
+ LongDouble& operator/= (const NativeImpl rhs) {
+ return this->assign (static_cast<NativeImpl> (*this) / rhs);
+ }
+ LongDouble& operator+= (const NativeImpl rhs) {
+ return this->assign (static_cast<NativeImpl> (*this) + rhs);
+ }
+ LongDouble& operator-= (const NativeImpl rhs) {
+ return this->assign (static_cast<NativeImpl> (*this) - rhs);
+ }
+ LongDouble& operator++ () {
+ return this->assign (static_cast<NativeImpl> (*this) + 1);
+ }
+ LongDouble& operator-- () {
+ return this->assign (static_cast<NativeImpl> (*this) - 1);
+ }
+ LongDouble operator++ (int) {
+ LongDouble ldv = *this;
+ this->assign (static_cast<NativeImpl> (*this) + 1);
+ return ldv;
+ }
+ LongDouble operator-- (int) {
+ LongDouble ldv = *this;
+ this->assign (static_cast<NativeImpl> (*this) - 1);
+ return ldv;
+ }
+
+ operator NativeImpl () const;
};
# endif /* ACE_SIZEOF_LONG_DOUBLE != 16 */
diff --git a/ACE/bin/tao_orb_tests.lst b/ACE/bin/tao_orb_tests.lst
index 1428facae20..24f61966eb6 100644
--- a/ACE/bin/tao_orb_tests.lst
+++ b/ACE/bin/tao_orb_tests.lst
@@ -111,6 +111,7 @@ TAO/tests/OBV/ValueBox/run_test.pl:
TAO/tests/OBV/Truncatable/run_test.pl:
TAO/tests/OBV/Simple/run_test.pl:
TAO/tests/Hello/run_test.pl:
+TAO/tests/LongDouble/run_test.pl:
TAO/tests/IPV6/run_test.pl: IPV6
TAO/tests/AlternateIIOP/run_test.pl:
TAO/tests/Optimized_Connection/run_test.pl: !DISABLE_ToFix_LynxOS_x86 !ACE_FOR_TAO