chiark / gitweb /
Refugees from Catacomb: low-level buffer primitives.
[mLib] / bits.h
diff --git a/bits.h b/bits.h
index 5ce1d9543e703edfc00c727a4783875b04b44324..b895dd4115cc2940dad45bdf7588a0aff32cebf7 100644 (file)
--- a/bits.h
+++ b/bits.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: bits.h,v 1.7 2000/07/22 09:48:26 mdw Exp $
+ * $Id$
  *
  * Portable bit-level manipulation macros
  *
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: bits.h,v $
- * Revision 1.7  2000/07/22 09:48:26  mdw
- * Added macros for reading 64-bit values.
- *
- * Revision 1.6  2000/07/16 12:28:28  mdw
- * Add 64-bit support, with faked arithmetic on 32-bit hosts.
- *
- * Revision 1.5  2000/06/17 10:36:06  mdw
- * Support for 24-bit types.
- *
- * Revision 1.4  1999/12/10 23:42:04  mdw
- * Change header file guard names.
- *
- * Revision 1.3  1999/06/20 23:31:52  mdw
- * More portability enhancements.
- *
- * Revision 1.2  1999/06/17 00:12:46  mdw
- * Improve portability for shift and rotate macros.
- *
- * Revision 1.1  1999/06/01 09:46:19  mdw
- * New addition: bit manipulation macros.
- *
- */
-
 #ifndef MLIB_BITS_H
 #define MLIB_BITS_H
 
 
 /*----- Decide on some types ----------------------------------------------*/
 
+/* --- Make GNU C shut up --- */
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
+#  define MLIB_BITS_EXTENSION __extension__
+#else
+#  define MLIB_BITS_EXTENSION
+#endif
+
 /* --- Decide on a 32-bit type --- *
  *
  * I want a type which is capable of expressing 32-bit numbers.  Because some
 #endif
 
 #if UINT_MAX >> 31 > 0xffffffff
-# define HAVE_UINT64
-  typedef unsigned int uint64;
+#  define HAVE_UINT64
+   typedef unsigned int uint64;
 #elif ULONG_MAX >> 31 > 0xffffffff
-# define HAVE_UINT64
-  typedef unsigned long uint64;
+#  define HAVE_UINT64
+   typedef unsigned long uint64;
 #elif defined(ULLONG_MAX)
-# define HAVE_UINT64
-  typedef unsigned long long uint64;
+#  define HAVE_UINT64
+   MLIB_BITS_EXTENSION typedef unsigned long long uint64;
 #endif
 
 #ifdef DEBUG64
@@ -144,13 +126,32 @@ typedef unsigned char octet;
 
 #define MASK8 0xffu
 #define MASK16 0xffffu
+#define MASK16_L 0xffffu
+#define MASK16_B 0xffffu
 #define MASK24 0xffffffu
+#define MASK24_L 0xffffffu
+#define MASK24_B 0xffffffu
 #define MASK32 0xffffffffu
+#define MASK32_L 0xffffffffu
+#define MASK32_B 0xffffffffu
 
 #ifdef HAVE_UINT64
-#  define MASK64 0xffffffffffffffffull
+#  define MASK64 MLIB_BITS_EXTENSION 0xffffffffffffffffu
 #endif
 
+/* --- Sizes --- */
+
+#define SZ_8 1
+#define SZ_16 2
+#define SZ_16_L 2
+#define SZ_16_B 2
+#define SZ_24 3
+#define SZ_24_L 3
+#define SZ_24_B 3
+#define SZ_32 4
+#define SZ_32_L 4
+#define SZ_32_B 4
+
 /* --- Type coercions --- */
 
 #define U8(x) ((octet)((x) & MASK8))
@@ -235,12 +236,15 @@ typedef unsigned char octet;
      unsigned _s = (s) & 63u;                                          \
      uint32 _l = (v).lo, _h = (v).hi;                                  \
      kludge64 *_d = &(d);                                              \
-     if (_s >= 32) {                                                   \
+     if (_s > 32) {                                                    \
        _d->hi = LSL32(_l, _s - 32u) | LSR32(_h, 64u - _s);             \
        _d->lo = LSL32(_h, _s - 32u) | LSR32(_l, 64u - _s);             \
      } else if (!_s) {                                                 \
        _d->lo = _l;                                                    \
        _d->hi = _h;                                                    \
+     } else if (_s == 32) {                                            \
+       _d->lo = _h;                                                    \
+       _d->hi = _l;                                                    \
      } else {                                                          \
        _d->hi = LSL32(_h, _s) | LSR32(_l, 32u - _s);                   \
        _d->lo = LSL32(_l, _s) | LSR32(_h, 32u - _s);                   \
@@ -250,12 +254,15 @@ typedef unsigned char octet;
      unsigned _s = (s) & 63u;                                          \
      uint32 _l = (v).lo, _h = (v).hi;                                  \
      kludge64 *_d = &(d);                                              \
-     if (_s >= 32) {                                                   \
+     if (_s > 32) {                                                    \
        _d->hi = LSR32(_l, _s - 32u) | LSL32(_h, 64u - _s);             \
        _d->lo = LSR32(_h, _s - 32u) | LSL32(_l, 64u - _s);             \
      } else if (!_s) {                                                 \
        _d->lo = _l;                                                    \
        _d->hi = _h;                                                    \
+     } else if (_s == 32) {                                            \
+       _d->lo = _h;                                                    \
+       _d->hi = _l;                                                    \
      } else {                                                          \
        _d->hi = LSR32(_h, _s) | LSL32(_l, 32u - _s);                   \
        _d->lo = LSR32(_l, _s) | LSL32(_h, 32u - _s);                   \
@@ -445,6 +452,14 @@ typedef unsigned char octet;
 #  define ZERO64(x) ((x).lo == 0 && (x).hi == 0)
 #endif
 
+/* --- Storing integers in tables --- */
+
+#ifdef HAVE_UINT64
+#  define X64(x, y) { 0x##x##y }
+#else
+#  define X64(x, y) { 0x##x, 0x##y }
+#endif
+    
 /*----- That's all, folks -------------------------------------------------*/
 
 #ifdef __cplusplus