This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository terminology.

View the commit online.

commit a4dad43122dd26a43913a298993f7f11c8cf73ee
Author: Cedric BAIL <[email protected]>
AuthorDate: Mon Aug 3 13:27:46 2026 -0600

    simd: add the record byte-OR kernel
    
    OR one bit into the same byte of every record of an array. The vector form only
    pays off when the stride lines up with the vector -- a 12-byte record repeats
    against a 16-byte vector every 48 bytes -- so every other stride falls through
    to the scalar form rather than pretending to be vectorised.
    
    No caller yet -- the autowrapped marking of saved rows takes it up.
    
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
 src/bin/simd/simd.c        | 51 ++++++++++++++++++++++++++++++++++++++++++++++
 src/bin/simd/simd.h        | 11 ++++++++++
 src/bin/simd/simd_neon.c   | 35 +++++++++++++++++++++++++++++++
 src/bin/simd/simd_scalar.c | 11 ++++++++++
 4 files changed, 108 insertions(+)

diff --git a/src/bin/simd/simd.c b/src/bin/simd/simd.c
index b7e11ef8..4a5592b0 100644
--- a/src/bin/simd/simd.c
+++ b/src/bin/simd/simd.c
@@ -58,6 +58,20 @@ simd_rscan_nonzero(const unsigned char *buf, size_t len)
    return simd_rscan_nonzero_scalar(buf, len);
 }
 
+void
+simd_records_or_byte(void *buf, size_t n, size_t rec, size_t off,
+                     unsigned char bit)
+{
+#if defined(TERMINOLOGY_HAVE_NEON)
+   if (EINA_LIKELY(_use_simd))
+     {
+        simd_records_or_byte_neon(buf, n, rec, off, bit);
+        return;
+     }
+#endif
+   simd_records_or_byte_scalar(buf, n, rec, off, bit);
+}
+
 void
 simd_widen_ascii(const unsigned char *buf, size_t len, Eina_Unicode *out)
 {
@@ -270,6 +284,42 @@ _test_rscan(void)
      }
 }
 
+static void
+_test_records_or(void)
+{
+   size_t n, off, rec, i;
+
+   /* Both the vectorised 12-byte stride and one that must fall back. */
+   for (rec = 11; rec <= 12; rec++)
+     {
+        for (n = 0; n <= 40; n++)
+          {
+             for (off = 0; off < rec; off++)
+               {
+                  unsigned char *a = _alloc_guarded(n * rec);
+                  unsigned char *b = _alloc_guarded(n * rec);
+
+                  for (i = 0; i < n * rec; i++)
+                    {
+                       unsigned char v = (unsigned char)(_rnd() & 0xff);
+
+                       a[GUARD + i] = v;
+                       b[GUARD + i] = v;
+                    }
+
+                  simd_records_or_byte_scalar(a + GUARD, n, rec, off, 0x40);
+                  simd_records_or_byte_neon(b + GUARD, n, rec, off, 0x40);
+
+                  assert(memcmp(a + GUARD, b + GUARD, n * rec) == 0);
+                  assert(_guards_intact(a, n * rec));
+                  assert(_guards_intact(b, n * rec));
+                  free(a);
+                  free(b);
+               }
+          }
+     }
+}
+
 static void
 _test_widen(void)
 {
@@ -367,6 +417,7 @@ tytest_simd_parity(void)
    _test_scan();
    _test_scan_u32();
    _test_rscan();
+   _test_records_or();
    _test_widen();
    _test_every_byte();
    _test_every_u32_boundary();
diff --git a/src/bin/simd/simd.h b/src/bin/simd/simd.h
index 343fe7fa..7583d822 100644
--- a/src/bin/simd/simd.h
+++ b/src/bin/simd/simd.h
@@ -35,6 +35,17 @@ size_t simd_rscan_nonzero_scalar(const unsigned char *buf, size_t len);
 size_t simd_rscan_nonzero_neon(const unsigned char *buf, size_t len);
 #endif
 
+/* OR 'bit' into byte 'off' of each of 'n' records of 'rec' bytes. 'off' must
+ * be less than 'rec'. */
+void simd_records_or_byte(void *buf, size_t n, size_t rec, size_t off,
+                          unsigned char bit);
+void simd_records_or_byte_scalar(void *buf, size_t n, size_t rec, size_t off,
+                                 unsigned char bit);
+#if defined(TERMINOLOGY_HAVE_NEON)
+void simd_records_or_byte_neon(void *buf, size_t n, size_t rec, size_t off,
+                               unsigned char bit);
+#endif
+
 /* Widen bytes already known to be plain printable ASCII into codepoints. */
 void simd_widen_ascii(const unsigned char *buf, size_t len, Eina_Unicode *out);
 void simd_widen_ascii_scalar(const unsigned char *buf, size_t len,
diff --git a/src/bin/simd/simd_neon.c b/src/bin/simd/simd_neon.c
index c132260b..3806798a 100644
--- a/src/bin/simd/simd_neon.c
+++ b/src/bin/simd/simd_neon.c
@@ -106,6 +106,41 @@ simd_rscan_nonzero_neon(const unsigned char *buf, size_t len)
    return 0;
 }
 
+void
+simd_records_or_byte_neon(void *buf, size_t n, size_t rec, size_t off,
+                          unsigned char bit)
+{
+   unsigned char *p = (unsigned char *)buf;
+   size_t i = 0;
+
+   /* A 12-byte stride lines up with the vector every four records, so the mask
+    * repeats every 48 bytes. Other strides use the scalar form. */
+   if ((rec == 12) && (off < rec))
+     {
+        unsigned char pat[48];
+        uint8x16_t m0, m1, m2;
+
+        memset(pat, 0, sizeof(pat));
+        pat[off] = bit;
+        pat[rec + off] = bit;
+        pat[2 * rec + off] = bit;
+        pat[3 * rec + off] = bit;
+        m0 = vld1q_u8(pat);
+        m1 = vld1q_u8(pat + 16);
+        m2 = vld1q_u8(pat + 32);
+
+        for (; i + 4 <= n; i += 4, p += 48)
+          {
+             vst1q_u8(p,      vorrq_u8(vld1q_u8(p),      m0));
+             vst1q_u8(p + 16, vorrq_u8(vld1q_u8(p + 16), m1));
+             vst1q_u8(p + 32, vorrq_u8(vld1q_u8(p + 32), m2));
+          }
+     }
+
+   for (; i < n; i++, p += rec)
+     p[off] |= bit;
+}
+
 void
 simd_widen_ascii_neon(const unsigned char *buf, size_t len, Eina_Unicode *out)
 {
diff --git a/src/bin/simd/simd_scalar.c b/src/bin/simd/simd_scalar.c
index 3676b94c..61c36e96 100644
--- a/src/bin/simd/simd_scalar.c
+++ b/src/bin/simd/simd_scalar.c
@@ -42,6 +42,17 @@ simd_rscan_nonzero_scalar(const unsigned char *buf, size_t len)
    return 0;
 }
 
+void
+simd_records_or_byte_scalar(void *buf, size_t n, size_t rec, size_t off,
+                            unsigned char bit)
+{
+   unsigned char *p = (unsigned char *)buf + off;
+   size_t i;
+
+   for (i = 0; i < n; i++, p += rec)
+     *p |= bit;
+}
+
 void
 simd_widen_ascii_scalar(const unsigned char *buf, size_t len, Eina_Unicode *out)
 {

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to