]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
include __builtin_popcount replacement function
authorDamien Miller <djm@mindrot.org>
Sun, 2 Mar 2025 11:06:53 +0000 (22:06 +1100)
committerDamien Miller <djm@mindrot.org>
Sun, 2 Mar 2025 11:06:53 +0000 (22:06 +1100)
Some systems/compilers lack __builtin_popcount(), so replace it as
necessary. Reported by Dennis Clarke; ok dtucker@

configure.ac
libcrux_mlkem768_sha3.h
mlkem768.sh

index f9c7729a54cf499bfb1990ed40c8bfcd06292bda..40fc1193fd6281be414c0568c76e0db7ff2f473c 100644 (file)
@@ -2084,6 +2084,19 @@ AC_CHECK_FUNCS([ \
        warn \
 ])
 
+AC_MSG_CHECKING([whether compiler supports __builtin_popcount])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+               #include <stdlib.h>
+       ]],
+       [[ int x = 123, y;
+          y = __builtin_popcount(123);
+          exit(y == 6 ? 0 : -1); ]])],
+       [ AC_MSG_RESULT([yes]) ], [
+               AC_MSG_RESULT([no])
+               AC_DEFINE([MISSING_BUILTIN_POPCOUNT], [1], [Define if your compiler lacks __builtin_popcount])
+       ]
+)
+
 AC_CHECK_DECLS([bzero, memmem])
 
 dnl Wide character support.
index b8ac1436f218abc3a39e7bfd5dd50f536b830f53..885e82bafa06527dddf22800c740095bcbff30c9 100644 (file)
@@ -177,10 +177,14 @@ static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) {
 }
 
 static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) {
-#ifdef _MSC_VER
+#if defined(_MSC_VER)
   return __popcnt(x0);
-#else
+#elif !defined(MISSING_BUILTIN_POPCOUNT)
   return __builtin_popcount(x0);
+#else
+  const uint8_t v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+  return v[x0 & 0xf] + v[(x0 >> 4) & 0xf];
+
 #endif
 }
 
index 3d12b2ed88e28fcd2745dae4c015ca4720f5c226..cbc3d14da2edfa4ed2f6360548fd864b0286ac80 100644 (file)
@@ -49,6 +49,11 @@ echo '#define KRML_HOST_EPRINTF(...)'
 echo '#define KRML_HOST_EXIT(x) fatal_f("internal error")'
 echo
 
+__builtin_popcount_replacement='
+  const uint8_t v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+  return v[x0 & 0xf] + v[(x0 >> 4) & 0xf];
+'
+
 for i in $FILES; do
        echo "/* from $i */"
        # Changes to all files:
@@ -62,7 +67,10 @@ for i in $FILES; do
                # Replace endian functions with versions that work.
                perl -0777 -pe 's/(static inline void core_num__u64_9__to_le_bytes.*\n)([^}]*\n)/\1  v = htole64(v);\n\2/' |
                perl -0777 -pe 's/(static inline uint64_t core_num__u64_9__from_le_bytes.*?)return v;/\1return le64toh(v);/s' |
-               perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s'
+               perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' |
+               # Compat for popcount.
+               perl -0777 -pe 's/\#ifdef (_MSC_VER)(.*?return __popcnt\(x0\);)/\#if defined(\1)\2/s' |
+               perl -0777 -pe "s/\\#else(\\n\\s+return __builtin_popcount\\(x0\\);)/\\#elif !defined(MISSING_BUILTIN_POPCOUNT)\\1\\n#else$__builtin_popcount_replacement/s"
                ;;
        # Default: pass through.
        *)