symm/blkc.h: Define a new `BLKC_ADD' macro.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 28 Oct 2018 22:51:57 +0000 (22:51 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 25 Nov 2018 11:38:04 +0000 (11:38 +0000)
And rewrite `BLKC_STEP' in terms of it.

symm/blkc.h

index 608dfcd..5e996e8 100644 (file)
   BLKC_GLUE(BLKC_XMOVE_, BLKC_TYPE(PRE))                               \
     (PRE, w, wx, BLKC_BITS(PRE))
 
-#define BLKC_STEP(PRE, w)                                              \
-  BLKC_GLUE(BLKC_STEP_X_, BLKC_ENDIAN(PRE))                            \
-    (PRE, w)
+#define BLKC_STEP(PRE, w) BLKC_ADD(PRE, w, 1)
+
+#define BLKC_ADD(PRE, w, n)                                            \
+  BLKC_GLUE(BLKC_ADD_X_, BLKC_ENDIAN(PRE))                             \
+    (PRE, w, n)
 
 #define BLKC_ZERO(PRE, w)                                              \
   BLKC_GLUE(BLKC_ZERO_, BLKC_TYPE(PRE))                                        \
   fputc('\n', stdout);                                                 \
 } while (0)
 
+/* --- Utilities --- *
+ *
+ * These seem too hard to properly generalize, or I'd have put them in
+ * <mLib/bits.h>.
+ */
+
+#ifdef HAVE_UINT64
+#  define BLKC_ADDC32(z_out, c_out, x, y) do {                         \
+     uint64 _t = (uint64)(x) + (y);                                    \
+     (z_out) = U32(_t); (c_out) = _t >> 32;                            \
+   } while (0)
+#else
+#  define BLKC_ADDC32(z_out, c_out, x, y) do {                         \
+     uint32 _x = (x), _c = 0, _t;                                      \
+     _t = U32(_x + (y)); (z_out) = _t; (c_out) = (_t < _x);            \
+   } while (0)
+#endif
+
 /* --- General implementation skeleton --- */
 
 #define BLKC_SKEL(PRE, decl, guts) do {                                        \
 #define BLKC_ZERO_X(PRE, w, n)                                         \
   BLKC_SKEL_X(PRE, BLKC_W(w);, *_w++ = 0;)
 
-#define BLKC_STEP_X_B(PRE, w) do {                                     \
-  unsigned _i = PRE##_BLKSZ/4; BLKC_W(w); uint32 _x = 0;               \
-  while (_i && !_x) { _i--; _w[_i] = _x = U32(_w[_i] + 1); }           \
+#define BLKC_ADD_X_B(PRE, w, n) do {                                   \
+  unsigned _i = PRE##_BLKSZ/4; BLKC_W(w); uint32 _n = (n);             \
+  while (_i-- && _n) BLKC_ADDC32(_w[_i], _n, _w[_i], _n);              \
 } while (0)
 
-#define BLKC_STEP_X_L(PRE, w) do {                                     \
-  unsigned _i = 0; BLKC_W(w); uint32 _x = 0;                           \
-  while (_i < PRE##_BLKSZ/4 && !_x)                                    \
-    { _w[_i] = _x = U32(_w[_i] + 1); _i++; }                           \
+#define BLKC_ADD_X_L(PRE, w, n) do {                                   \
+  unsigned _i = 0; BLKC_W(w); uint32 _n = (n);                         \
+  while (_i < PRE##_BLKSZ/4 && _n)                                     \
+    { BLKC_ADDC32(_w[_i], _n, _w[_i], _n); _i++; }                     \
 } while (0)
 
 #define BLKC_SET_X_B(PRE, w, x) do {                                   \