This new module defines the stdc_memreverse8 function.

2026-03-15  Bruno Haible  <[email protected]>

        stdc_memreverse8: Add tests.
        * tests/test-stdc_memreverse8.c: New file.
        * modules/stdc_memreverse8-tests: New file.

        stdc_memreverse8: New module.
        * lib/stdbit.in.h: Include <stddef.h>.
        (_GL_STDC_MEMREVERSE8_INLINE): New macro.
        (stdc_memreverse8): New function.
        * lib/stdc_memreverse8.c: New file.
        * m4/stdbit_h.m4 (gl_STDBIT_H_REQUIRE_DEFAULTS): Initialize
        GNULIB_STDC_MEMREVERSE8.
        * modules/stdbit-h (Makefile.am): Substitute GNULIB_STDC_MEMREVERSE8.
        * modules/stdc_memreverse8: New file.
        * doc/posix-functions/stdc_memreverse8.texi: Mention the new module.

From d5be14cfa120a18adb9c308db55173653fc67e39 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 15 Mar 2026 14:35:48 +0100
Subject: [PATCH 1/2] stdc_memreverse8: New module.

* lib/stdbit.in.h: Include <stddef.h>.
(_GL_STDC_MEMREVERSE8_INLINE): New macro.
(stdc_memreverse8): New function.
* lib/stdc_memreverse8.c: New file.
* m4/stdbit_h.m4 (gl_STDBIT_H_REQUIRE_DEFAULTS): Initialize
GNULIB_STDC_MEMREVERSE8.
* modules/stdbit-h (Makefile.am): Substitute GNULIB_STDC_MEMREVERSE8.
* modules/stdc_memreverse8: New file.
* doc/posix-functions/stdc_memreverse8.texi: Mention the new module.
---
 ChangeLog                                 | 13 ++++++++
 doc/posix-functions/stdc_memreverse8.texi |  9 +++---
 lib/stdbit.in.h                           | 38 +++++++++++++++++++++++
 lib/stdc_memreverse8.c                    | 19 ++++++++++++
 m4/stdbit_h.m4                            |  3 +-
 modules/stdbit-h                          |  1 +
 modules/stdc_memreverse8                  | 26 ++++++++++++++++
 7 files changed, 104 insertions(+), 5 deletions(-)
 create mode 100644 lib/stdc_memreverse8.c
 create mode 100644 modules/stdc_memreverse8

diff --git a/ChangeLog b/ChangeLog
index 2c930fe802..47430a0862 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2026-03-15  Bruno Haible  <[email protected]>
+
+	stdc_memreverse8: New module.
+	* lib/stdbit.in.h: Include <stddef.h>.
+	(_GL_STDC_MEMREVERSE8_INLINE): New macro.
+	(stdc_memreverse8): New function.
+	* lib/stdc_memreverse8.c: New file.
+	* m4/stdbit_h.m4 (gl_STDBIT_H_REQUIRE_DEFAULTS): Initialize
+	GNULIB_STDC_MEMREVERSE8.
+	* modules/stdbit-h (Makefile.am): Substitute GNULIB_STDC_MEMREVERSE8.
+	* modules/stdc_memreverse8: New file.
+	* doc/posix-functions/stdc_memreverse8.texi: Mention the new module.
+
 2026-03-15  Bruno Haible  <[email protected]>
 
 	byteswap: Rely on <stdbit.h>.
diff --git a/doc/posix-functions/stdc_memreverse8.texi b/doc/posix-functions/stdc_memreverse8.texi
index fd9f7344a9..33a164ebb6 100644
--- a/doc/posix-functions/stdc_memreverse8.texi
+++ b/doc/posix-functions/stdc_memreverse8.texi
@@ -7,15 +7,16 @@
 @url{https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3783.pdf})
 section 7.18.19.
 
-Gnulib module: ---
+Gnulib module: stdc_memreverse8
+@mindex stdc_memreverse8
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on many platforms:
+glibc 2.43, macOS 26, FreeBSD 15.0, NetBSD 10.0, OpenBSD 7.8, AIX 7.3.1, HP-UX 11.31, Solaris 11.4, Cygwin 3.5.3, mingw, MSVC 17, Android 15.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This function is missing on many platforms:
-glibc 2.43, macOS 26, FreeBSD 15.0, NetBSD 10.0, OpenBSD 7.8, AIX 7.3.1, HP-UX 11.31, Solaris 11.4, Cygwin 3.5.3, mingw, MSVC 17, Android 15.
 @end itemize
diff --git a/lib/stdbit.in.h b/lib/stdbit.in.h
index 65aab488cd..e7d7e7a9ee 100644
--- a/lib/stdbit.in.h
+++ b/lib/stdbit.in.h
@@ -37,6 +37,13 @@
  #error "Please include config.h first."
 #endif
 
+#if @GNULIB_STDC_MEMREVERSE8@
+
+/* Get size_t.  */
+# include <stddef.h>
+
+#endif
+
 #if @GNULIB_STDC_MEMREVERSE8U@ || @GNULIB_STDC_LOAD8_ALIGNED@ || @GNULIB_STDC_LOAD8@ || @GNULIB_STDC_STORE8_ALIGNED@ || @GNULIB_STDC_STORE8@
 
 /* Get uint8_t, uint16_t, uint32_t, uint64_t,
@@ -134,6 +141,9 @@ _GL_INLINE_HEADER_BEGIN
 #ifndef _GL_STDC_BIT_CEIL_INLINE
 # define _GL_STDC_BIT_CEIL_INLINE _GL_INLINE
 #endif
+#ifndef _GL_STDC_MEMREVERSE8_INLINE
+# define _GL_STDC_MEMREVERSE8_INLINE _GL_INLINE
+#endif
 #ifndef _GL_STDC_MEMREVERSE8U_INLINE
 # define _GL_STDC_MEMREVERSE8U_INLINE _GL_INLINE
 #endif
@@ -1151,6 +1161,34 @@ stdc_bit_ceil_ull (unsigned long long int n)
 #endif /* @HAVE_STDBIT_H@ */
 
 
+/* ISO C2y ?? 7.18.19 8-bit Memory Reversal  */
+
+#if @GNULIB_STDC_MEMREVERSE8@
+
+_GL_STDC_MEMREVERSE8_INLINE void
+stdc_memreverse8 (size_t n, unsigned char *ptr)
+{
+  if (n > 0)
+    {
+      /* There is no need to optimize the cases N == 1, N == 2, N == 4
+         specially using __builtin_constant_p, because GCC does the possible
+         optimizations already, taking into account the alignment of PTR:
+         GCC >= 3 for N == 1, GCC >= 8 for N == 2, GCC >= 13 for N == 4.
+         (Whereas clang >= 3, <= 22 optimizes only the case N == 1.)  */
+      size_t i, j;
+      for (i = 0, j = n-1; i < j; i++, j--)
+        {
+          unsigned char xi = ptr[i];
+          unsigned char xj = ptr[j];
+          ptr[j] = xi;
+          ptr[i] = xj;
+        }
+    }
+}
+
+#endif
+
+
 /* ISO C2y ?? 7.18.20 Exact-width 8-bit Memory Reversal  */
 
 #if @GNULIB_STDC_MEMREVERSE8U@
diff --git a/lib/stdc_memreverse8.c b/lib/stdc_memreverse8.c
new file mode 100644
index 0000000000..a800b2dab5
--- /dev/null
+++ b/lib/stdc_memreverse8.c
@@ -0,0 +1,19 @@
+/* stdc_memreverse8 function.
+   Copyright (C) 2026 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#define _GL_STDC_MEMREVERSE8_INLINE _GL_EXTERN_INLINE
+#include <config.h>
+#include <stdbit.h>
diff --git a/m4/stdbit_h.m4 b/m4/stdbit_h.m4
index e279697e2c..a84aa3c8cb 100644
--- a/m4/stdbit_h.m4
+++ b/m4/stdbit_h.m4
@@ -1,5 +1,5 @@
 # stdbit_h.m4
-# serial 10
+# serial 11
 dnl Copyright 2024-2026 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -66,6 +66,7 @@ AC_DEFUN([gl_STDBIT_H_REQUIRE_DEFAULTS]
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDC_BIT_WIDTH])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDC_BIT_FLOOR])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDC_BIT_CEIL])
+    gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDC_MEMREVERSE8])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDC_MEMREVERSE8U])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDC_LOAD8_ALIGNED])
     gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDC_LOAD8])
diff --git a/modules/stdbit-h b/modules/stdbit-h
index 7a02a0df55..1c1f76e358 100644
--- a/modules/stdbit-h
+++ b/modules/stdbit-h
@@ -46,6 +46,7 @@ stdbit.h: stdbit.in.h $(top_builddir)/config.status
 	  -e 's/@''GNULIB_STDC_BIT_WIDTH''@/$(GNULIB_STDC_BIT_WIDTH)/g' \
 	  -e 's/@''GNULIB_STDC_BIT_FLOOR''@/$(GNULIB_STDC_BIT_FLOOR)/g' \
 	  -e 's/@''GNULIB_STDC_BIT_CEIL''@/$(GNULIB_STDC_BIT_CEIL)/g' \
+	  -e 's/@''GNULIB_STDC_MEMREVERSE8''@/$(GNULIB_STDC_MEMREVERSE8)/g' \
 	  -e 's/@''GNULIB_STDC_MEMREVERSE8U''@/$(GNULIB_STDC_MEMREVERSE8U)/g' \
 	  -e 's/@''GNULIB_STDC_LOAD8_ALIGNED''@/$(GNULIB_STDC_LOAD8_ALIGNED)/g' \
 	  -e 's/@''GNULIB_STDC_LOAD8''@/$(GNULIB_STDC_LOAD8)/g' \
diff --git a/modules/stdc_memreverse8 b/modules/stdc_memreverse8
new file mode 100644
index 0000000000..345d087e28
--- /dev/null
+++ b/modules/stdc_memreverse8
@@ -0,0 +1,26 @@
+Description:
+stdc_memreverse8 function: Swap bytes in memory.
+
+Files:
+lib/stdc_memreverse8.c
+
+Depends-on:
+stdbit-h
+
+configure.ac:
+AC_REQUIRE([gl_STDBIT_H])
+gl_STDBIT_MODULE_INDICATOR([stdc_memreverse8])
+
+Makefile.am:
+if GL_GENERATE_STDBIT_H
+lib_SOURCES += stdc_memreverse8.c
+endif
+
+Include:
+<stdbit.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all
-- 
2.52.0

>From 057b44988bec89961215d46fb487d23ff3906c57 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Sun, 15 Mar 2026 14:48:43 +0100
Subject: [PATCH 2/2] stdc_memreverse8: Add tests.

* tests/test-stdc_memreverse8.c: New file.
* modules/stdc_memreverse8-tests: New file.
---
 ChangeLog                      |  4 ++
 modules/stdc_memreverse8-tests | 11 +++++
 tests/test-stdc_memreverse8.c  | 77 ++++++++++++++++++++++++++++++++++
 3 files changed, 92 insertions(+)
 create mode 100644 modules/stdc_memreverse8-tests
 create mode 100644 tests/test-stdc_memreverse8.c

diff --git a/ChangeLog b/ChangeLog
index 47430a0862..b5c4cc6bdb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2026-03-15  Bruno Haible  <[email protected]>
 
+	stdc_memreverse8: Add tests.
+	* tests/test-stdc_memreverse8.c: New file.
+	* modules/stdc_memreverse8-tests: New file.
+
 	stdc_memreverse8: New module.
 	* lib/stdbit.in.h: Include <stddef.h>.
 	(_GL_STDC_MEMREVERSE8_INLINE): New macro.
diff --git a/modules/stdc_memreverse8-tests b/modules/stdc_memreverse8-tests
new file mode 100644
index 0000000000..e0e01ff5c4
--- /dev/null
+++ b/modules/stdc_memreverse8-tests
@@ -0,0 +1,11 @@
+Files:
+tests/test-stdc_memreverse8.c
+tests/macros.h
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-stdc_memreverse8
+check_PROGRAMS += test-stdc_memreverse8
diff --git a/tests/test-stdc_memreverse8.c b/tests/test-stdc_memreverse8.c
new file mode 100644
index 0000000000..f769500571
--- /dev/null
+++ b/tests/test-stdc_memreverse8.c
@@ -0,0 +1,77 @@
+/* Test of stdc_memreverse8 function.
+   Copyright (C) 2026 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <[email protected]>, 2026.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <stdbit.h>
+
+#include "macros.h"
+
+static unsigned char data[10] =
+  { 0x12, 0x31, 0x47, 0xBF, 0xC4, 0xD3, 0xEE, 0xF1, 0x90, 0x44 };
+
+static unsigned char *volatile ptr;
+
+int
+main (void)
+{
+  ptr = data;
+
+  stdc_memreverse8 (0, ptr + 5);
+  /* Expect: 0x12, 0x31, 0x47, 0xBF, 0xC4, 0xD3, 0xEE, 0xF1, 0x90, 0x44  */
+  ASSERT (ptr[4] == 0xC4);
+  ASSERT (ptr[5] == 0xD3);
+
+  stdc_memreverse8 (1, ptr + 5);
+  /* Expect: 0x12, 0x31, 0x47, 0xBF, 0xC4, 0xD3, 0xEE, 0xF1, 0x90, 0x44  */
+  ASSERT (ptr[4] == 0xC4);
+  ASSERT (ptr[5] == 0xD3);
+  ASSERT (ptr[6] == 0xEE);
+
+  stdc_memreverse8 (2, ptr + 5);
+  /* Expect: 0x12, 0x31, 0x47, 0xBF, 0xC4, 0xEE, 0xD3, 0xF1, 0x90, 0x44  */
+  ASSERT (ptr[4] == 0xC4);
+  ASSERT (ptr[5] == 0xEE);
+  ASSERT (ptr[6] == 0xD3);
+  ASSERT (ptr[7] == 0xF1);
+
+  stdc_memreverse8 (4, ptr + 3);
+  /* Expect: 0x12, 0x31, 0x47, 0xD3, 0xEE, 0xC4, 0xBF, 0xF1, 0x90, 0x44  */
+  ASSERT (ptr[2] == 0x47);
+  ASSERT (ptr[3] == 0xD3);
+  ASSERT (ptr[4] == 0xEE);
+  ASSERT (ptr[5] == 0xC4);
+  ASSERT (ptr[6] == 0xBF);
+  ASSERT (ptr[7] == 0xF1);
+
+  stdc_memreverse8 (8, ptr + 1);
+  /* Expect: 0x12, 0x90, 0xF1, 0xBF, 0xC4, 0xEE, 0xD3, 0x47, 0x31, 0x44  */
+  ASSERT (ptr[0] == 0x12);
+  ASSERT (ptr[1] == 0x90);
+  ASSERT (ptr[2] == 0xF1);
+  ASSERT (ptr[3] == 0xBF);
+  ASSERT (ptr[4] == 0xC4);
+  ASSERT (ptr[5] == 0xEE);
+  ASSERT (ptr[6] == 0xD3);
+  ASSERT (ptr[7] == 0x47);
+  ASSERT (ptr[8] == 0x31);
+  ASSERT (ptr[9] == 0x44);
+
+  return test_exit_status;
+}
-- 
2.52.0

Reply via email to