diff aclocal.m4 @ 8169:66bc6f9b4f72

rewrite integer arithmetics and conversions
author Jaroslav Hajek <highegg@gmail.com>
date Wed, 01 Oct 2008 11:05:13 -0400
parents 0ef13e15319b
children dee5d60257e4
line wrap: on
line diff
--- a/aclocal.m4	Tue Sep 30 09:19:43 2008 +0200
+++ b/aclocal.m4	Wed Oct 01 11:05:13 2008 -0400
@@ -1206,3 +1206,68 @@
    AC_SUBST([FT2_CFLAGS])
    AC_SUBST([FT2_LIBS])])
 dnl end of freetype2.m4
+
+dnl Check whether fast signed integer arithmetics using bit tricks
+dnl can be used in oct-inttypes.h. Defines HAVE_FAST_INT_OPS if
+dnl the following conditions hold:
+dnl 1. Signed numbers are represented by twos complement
+dnl    (see <http://en.wikipedia.org/wiki/Two%27s_complement>)
+dnl 2. static_cast to unsigned int counterpart works like interpreting
+dnl    the signed bit pattern as unsigned (and is thus zero-cost).
+dnl 3. Signed addition and subtraction yield the same bit results as unsigned.
+dnl    (We use casts to prevent optimization interference, so there is no
+dnl     need for things like -ftrapv).
+dnl 4. Bit operations on signed integers work like on unsigned integers,
+dnl    except for the shifts. Shifts are arithmetic.
+dnl
+AC_DEFUN([OCTAVE_FAST_INT_OPS],[
+AC_MSG_CHECKING([whether fast integer arithmetics is usable])
+AC_LANG_PUSH(C++)
+AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <limits>
+template<class UT, class ST>
+static bool 
+do_test (UT, ST)
+{
+  volatile ST s = std::numeric_limits<ST>::min () / 3;
+  volatile UT u = static_cast<UT> (s);
+  if (*(reinterpret_cast<volatile ST *> (&u)) != s) return true;
+  
+  u = 0; u = ~u;
+  if (*(reinterpret_cast<volatile ST *> (&u)) != -1) return true;
+  
+  ST sx, sy;
+  sx = std::numeric_limits<ST>::max () / 2 + 1;
+  sy = std::numeric_limits<ST>::max () / 2 + 2;
+  if (static_cast<ST> (static_cast<UT> (sx) + static_cast<UT> (sy))
+      != std::numeric_limits<ST>::min () + 1) return true;
+  if (static_cast<ST> (static_cast<UT> (sx) - static_cast<UT> (sy))
+      != -1) return true;
+  
+  if ((sx & sy) != (static_cast<UT> (sx) & static_cast<UT> (sy)))
+    return true;
+  if ((sx | sy) != (static_cast<UT> (sx) | static_cast<UT> (sy)))
+    return true;
+  if ((sx ^ sy) != (static_cast<UT> (sx) ^ static_cast<UT> (sy)))
+    return true;
+  if ((-1 >> 1) != -1) return true;
+  return false;
+}
+
+#define DO_TEST(T) \
+if (do_test (static_cast<unsigned T> (0), static_cast<signed T> (0))) \
+  return sizeof (T);
+]],[[
+  DO_TEST(char)
+  DO_TEST(short)
+  DO_TEST(int)
+  DO_TEST(long)
+#if (defined(HAVE_LONG_LONG_INT) && defined(HAVE_UNSIGNED_LONG_LONG_INT))
+  DO_TEST(long long)
+#endif
+]])],
+[AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_FAST_INT_OPS,1,[Define if signed integers use two's complement])],
+[AC_MSG_RESULT([no])])
+AC_LANG_POP(C++)])
+