utils/bits.h: Refactor the load/store macros.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 26 May 2018 15:22:39 +0000 (16:22 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 26 May 2018 17:27:30 +0000 (18:27 +0100)
  * Each macro is now only defined conditionally.  This allows earlier
    parts of the header file to define a compiler-specific
    implementation, with the generic definitions filling in the blanks.

  * Instead of writing the byte manipulations out longhand, build each
    one out of smaller pieces.  This has two benefits: firstly, the new
    definitions are smaller and easier to understand; and, secondly, if
    there's a compiler-specific trick for, say 16-bit loads, then 32-bit
    loads can win some of the benefit.

utils/bits.h

index f3fe08f..6602e43 100644 (file)
@@ -322,109 +322,105 @@ typedef unsigned char octet, uint8;
 #define LOAD8(p) (GETBYTE((p), 0))
 #define STORE8(p, v) (PUTBYTE((p), 0, (v)))
 
-#define LOAD16_B(p)                                                    \
-  (((uint16)GETBYTE((p), 0) << 8) |                                    \
-   ((uint16)GETBYTE((p), 1) << 0))
-#define LOAD16_L(p)                                                    \
-  (((uint16)GETBYTE((p), 0) << 0) |                                    \
-   ((uint16)GETBYTE((p), 1) << 8))
+#ifndef LOAD16_B
+#  define LOAD16_B(p)
+       (((uint16)GETBYTE((p), 0) << 8) |                               \
+        ((uint16)GETBYTE((p), 1) << 0))
+#endif
+#ifndef LOAD16_L
+#  define LOAD16_L(p)                                                  \
+       (((uint16)GETBYTE((p), 0) << 0) |                               \
+        ((uint16)GETBYTE((p), 1) << 8))
+#endif
 #define LOAD16(p) LOAD16_B((p))
 
-#define STORE16_B(p, v)                                                        \
-  (PUTBYTE((p), 0, (uint16)(v) >> 8),                                  \
-   PUTBYTE((p), 1, (uint16)(v) >> 0))
-#define STORE16_L(p, v)                                                        \
-  (PUTBYTE((p), 0, (uint16)(v) >> 0),                                  \
-   PUTBYTE((p), 1, (uint16)(v) >> 8))
+#ifndef STORE16_B
+#  define STORE16_B(p, v)                                              \
+       (PUTBYTE((p), 0, (uint16)(v) >> 8),                             \
+        PUTBYTE((p), 1, (uint16)(v) >> 0))
+#endif
+#ifndef STORE16_L
+#  define STORE16_L(p, v)                                              \
+       (PUTBYTE((p), 0, (uint16)(v) >> 0),                             \
+        PUTBYTE((p), 1, (uint16)(v) >> 8))
+#endif
 #define STORE16(p, v) STORE16_B((p), (v))
 
-#define LOAD24_B(p)                                                    \
-  (((uint24)GETBYTE((p), 0) << 16) |                                   \
-   ((uint24)GETBYTE((p), 1) << 8) |                                    \
-   ((uint24)GETBYTE((p), 2) << 0))
-#define LOAD24_L(p)                                                    \
-  (((uint24)GETBYTE((p), 0) << 0) |                                    \
-   ((uint24)GETBYTE((p), 1) << 8) |                                    \
-   ((uint24)GETBYTE((p), 2) << 16))
+#ifndef LOAD24_B
+#  define LOAD24_B(p)                                                  \
+       (((uint24)GETBYTE((p), 0)            << 16) |                   \
+        ((uint24)LOAD16_B((octet *)(p) + 1) <<  0))
+#endif
+#ifndef LOAD24_L
+#  define LOAD24_L(p)                                                  \
+       (((uint24)LOAD16_L((octet *)(p) + 0) <<  0) |                   \
+        ((uint24)GETBYTE((p), 2)            << 16))
+#endif
 #define LOAD24(p) LOAD24_B((p))
 
-#define STORE24_B(p, v)                                                        \
-  (PUTBYTE((p), 0, (uint24)(v) >> 16),                                 \
-   PUTBYTE((p), 1, (uint24)(v) >>  8),                                 \
-   PUTBYTE((p), 2, (uint24)(v) >>  0))
-#define STORE24_L(p, v)                                                        \
-  (PUTBYTE((p), 0, (uint24)(v) >>  0),                                 \
-   PUTBYTE((p), 1, (uint24)(v) >>  8),                                 \
-   PUTBYTE((p), 2, (uint24)(v) >> 16))
+#ifndef STORE24_B
+#  define STORE24_B(p, v)                                              \
+       (PUTBYTE((p), 0,             (uint24)(v) >> 16),                \
+        STORE16_B((octet *)(p) + 1, (uint24)(v) >>  0))
+#endif
+#ifndef STORE24_L
+#  define STORE24_L(p, v)                                              \
+       (STORE16_L((octet *)(p) + 0, (uint24)(v) >>  0),                \
+        PUTBYTE((p), 2,             (uint24)(v) >> 16))
+#endif
 #define STORE24(p, v) STORE24_B((p), (v))
 
-#define LOAD32_B(p)                                                    \
-  (((uint32)GETBYTE((p), 0) << 24) |                                   \
-   ((uint32)GETBYTE((p), 1) << 16) |                                   \
-   ((uint32)GETBYTE((p), 2) << 8) |                                    \
-   ((uint32)GETBYTE((p), 3) << 0))
-#define LOAD32_L(p)                                                    \
-  (((uint32)GETBYTE((p), 0) << 0) |                                    \
-   ((uint32)GETBYTE((p), 1) << 8) |                                    \
-   ((uint32)GETBYTE((p), 2) << 16) |                                   \
-   ((uint32)GETBYTE((p), 3) << 24))
+#ifndef LOAD32_B
+#  define LOAD32_B(p)                                                  \
+       (((uint32)LOAD16_B((octet *)(p) + 0) << 16) |                   \
+        ((uint32)LOAD16_B((octet *)(p) + 2) <<  0))
+#endif
+#ifndef LOAD32_L
+#  define LOAD32_L(p)                                                  \
+       (((uint32)LOAD16_L((octet *)(p) + 0) <<  0) |                   \
+        ((uint32)LOAD16_L((octet *)(p) + 2) << 16))
+#endif
 #define LOAD32(p) LOAD32_B((p))
 
-#define STORE32_B(p, v)                                                        \
-  (PUTBYTE((p), 0, (uint32)(v) >> 24),                                 \
-   PUTBYTE((p), 1, (uint32)(v) >> 16),                                 \
-   PUTBYTE((p), 2, (uint32)(v) >>  8),                                 \
-   PUTBYTE((p), 3, (uint32)(v) >>  0))
-#define STORE32_L(p, v)                                                        \
-  (PUTBYTE((p), 0, (uint32)(v) >>  0),                                 \
-   PUTBYTE((p), 1, (uint32)(v) >>  8),                                 \
-   PUTBYTE((p), 2, (uint32)(v) >> 16),                                 \
-   PUTBYTE((p), 3, (uint32)(v) >> 24))
+#ifndef STORE32_B
+#  define STORE32_B(p, v)                                              \
+       (STORE16_B((octet *)(p) + 0, (uint32)(v) >> 16),                \
+        STORE16_B((octet *)(p) + 2, (uint32)(v) >>  0))
+#endif
+#ifndef STORE32_L
+#  define STORE32_L(p, v)                                              \
+       (STORE16_L((octet *)(p) + 0, (uint32)(v) >>  0),                \
+        STORE16_L((octet *)(p) + 2, (uint32)(v) >> 16))
+#endif
 #define STORE32(p, v) STORE32_B((p), (v))
 
 #ifdef HAVE_UINT64
 
-#  define LOAD64_B(p)                                                  \
-    (((uint64)GETBYTE((p), 0) << 56) |                                 \
-     ((uint64)GETBYTE((p), 1) << 48) |                                 \
-     ((uint64)GETBYTE((p), 2) << 40) |                                 \
-     ((uint64)GETBYTE((p), 3) << 32) |                                 \
-     ((uint64)GETBYTE((p), 4) << 24) |                                 \
-     ((uint64)GETBYTE((p), 5) << 16) |                                 \
-     ((uint64)GETBYTE((p), 6) <<  8) |                                 \
-     ((uint64)GETBYTE((p), 7) <<  0))
-#  define LOAD64_L(p)                                                  \
-    (((uint64)GETBYTE((p), 0) <<  0) |                                 \
-     ((uint64)GETBYTE((p), 1) <<  8) |                                 \
-     ((uint64)GETBYTE((p), 2) << 16) |                                 \
-     ((uint64)GETBYTE((p), 3) << 24) |                                 \
-     ((uint64)GETBYTE((p), 4) << 32) |                                 \
-     ((uint64)GETBYTE((p), 5) << 40) |                                 \
-     ((uint64)GETBYTE((p), 6) << 48) |                                 \
-     ((uint64)GETBYTE((p), 7) << 56))
+#  ifndef LOAD64_B
+#    define LOAD64_B(p)                                                        \
+       (((uint64)LOAD32_B((octet *)(p) + 0) << 32) |                   \
+        ((uint64)LOAD32_B((octet *)(p) + 4) <<  0))
+#  endif
+#  ifndef LOAD64_L
+#    define LOAD64_L(p)                                                        \
+       (((uint64)LOAD32_L((octet *)(p) + 0) <<  0) |                   \
+        ((uint64)LOAD32_L((octet *)(p) + 4) << 32))
+#  endif
 #  define LOAD64(p) LOAD64_B((p))
 #  define LOAD64_B_(d, p) ((d).i = LOAD64_B((p)))
 #  define LOAD64_L_(d, p) ((d).i = LOAD64_L((p)))
 #  define LOAD64_(d, p) LOAD64_B_((d), (p))
 
-#  define STORE64_B(p, v)                                              \
-    (PUTBYTE((p), 0, (uint64)(v) >> 56),                               \
-     PUTBYTE((p), 1, (uint64)(v) >> 48),                               \
-     PUTBYTE((p), 2, (uint64)(v) >> 40),                               \
-     PUTBYTE((p), 3, (uint64)(v) >> 32),                               \
-     PUTBYTE((p), 4, (uint64)(v) >> 24),                               \
-     PUTBYTE((p), 5, (uint64)(v) >> 16),                               \
-     PUTBYTE((p), 6, (uint64)(v) >>  8),                               \
-     PUTBYTE((p), 7, (uint64)(v) >>  0))
-#  define STORE64_L(p, v)                                              \
-    (PUTBYTE((p), 0, (uint64)(v) >>  0),                               \
-     PUTBYTE((p), 1, (uint64)(v) >>  8),                               \
-     PUTBYTE((p), 2, (uint64)(v) >> 16),                               \
-     PUTBYTE((p), 3, (uint64)(v) >> 24),                               \
-     PUTBYTE((p), 4, (uint64)(v) >> 32),                               \
-     PUTBYTE((p), 5, (uint64)(v) >> 40),                               \
-     PUTBYTE((p), 6, (uint64)(v) >> 48),                               \
-     PUTBYTE((p), 7, (uint64)(v) >> 56))
+#  ifndef STORE64_B
+#    define STORE64_B(p, v)                                            \
+       (STORE32_B((octet *)(p) + 0, (uint64)(v) >> 32),                \
+        STORE32_B((octet *)(p) + 4, (uint64)(v) >>  0))
+#  endif
+#  ifndef STORE64_L
+#    define STORE64_L(p, v)                                            \
+       (STORE32_L((octet *)(p) + 0, (uint64)(v) >>  0),                \
+        STORE32_L((octet *)(p) + 4, (uint64)(v) >> 32))
+#  endif
 #  define STORE64(p, v) STORE64_B((p), (v))
 #  define STORE64_B_(p, v) STORE64_B((p), (v).i)
 #  define STORE64_L_(p, v) STORE64_L((p), (v).i)