Restores what was broken by https://github.com/mysql/mysql-server/commit/07bf1bdb620daf62c02ead0d5439d65c7c34aa00
Adds extra fixes, somewhat hackerish.

--- a/include/base64.h	2025-09-24 21:35:03.000000000 +0800
+++ b/include/base64.h	2025-12-14 23:19:44.000000000 +0800
@@ -213,12 +213,20 @@
 /*
   Maximum length base64_encode_needed_length() can accept with no overflow.
 */
-constexpr inline uint64 base64_encode_max_arg_length() {
+static inline uint64 base64_encode_max_arg_length() {
+#if (SIZEOF_VOIDP == 8)
   /*
     6827690988321067803 ->   9223372036854775805
     6827690988321067804 ->  -9223372036854775807
   */
   return 0x5EC0D4C77B03531BLL;
+#else
+  /*
+    1589695686 ->  2147483646
+    1589695687 -> -2147483645
+  */
+  return 0x5EC0D4C6;
+#endif
 }
 
 /*
@@ -233,8 +241,12 @@
 /*
   Maximum length base64_decode_needed_length() can accept with no overflow.
 */
-constexpr inline uint64 base64_decode_max_arg_length() {
+static inline uint64 base64_decode_max_arg_length() {
+#if (SIZEOF_VOIDP == 8)
   return 0x2AAAAAAAAAAAAAAALL;
+#else
+  return 0x2AAAAAAA;
+#endif
 }
 
 /*

--- a/sql/item.cc	2025-09-24 21:35:03.000000000 +0800
+++ b/sql/item.cc	2025-12-14 23:18:39.000000000 +0800
@@ -9768,9 +9768,9 @@
     return my_decimal_cmp(field_val, item_val);
   }
 
-  const double result = item->val_real();
+  volatile double result = item->val_real();
   if (item->null_value) return 0;
-  const double field_result = field->val_real();
+  volatile double field_result = field->val_real();
   if (field_result < result)
     return -1;
   else if (field_result > result)

--- a/cmake/boost.cmake	2025-09-24 21:35:03.000000000 +0800
+++ b/cmake/boost.cmake	2025-12-14 23:19:11.000000000 +0800
@@ -40,6 +40,12 @@
 TARGET_INCLUDE_DIRECTORIES(boost SYSTEM BEFORE INTERFACE
   ${BOOST_PATCHES_DIR} ${BOOST_INCLUDE_DIR})
 
+# TODO: still relevant?
+# Bug in sqrt(NaN) on 32-bit platforms
+IF(SIZEOF_VOIDP EQUAL 4)
+  TARGET_COMPILE_DEFINITIONS(boost INTERFACE BOOST_GEOMETRY_SQRT_CHECK_FINITENESS)
+ENDIF()
+
 IF(NOT WIN32)
   # See boost/container_hash/hash.hpp
   # We pretend that the compiler is pre-c++98, in order to hide the


!THIS IS A HACK!
--- a/storage/temptable/include/temptable/lock_free_type.h	2025-09-24 21:35:03.000000000 +0800
+++ b/storage/temptable/include/temptable/lock_free_type.h	2025-12-14 23:20:23.000000000 +0800
@@ -35,6 +35,10 @@
 
 namespace temptable {
 
+#if defined(__GNUC__) && (SIZEOF_VOIDP == 4) && (ATOMIC_LLONG_LOCK_FREE == 1) && !defined(__clang__)
+#define GCC_USE_LIBATOMIC
+#endif
+
 /** Enum class describing alignment-requirements. */
 enum class Alignment { NATURAL, L1_DCACHE_SIZE };
 
@@ -112,7 +116,7 @@
     T,
     typename std::enable_if<std::is_same<T, long long>::value or
                             std::is_same<T, unsigned long long>::value>::type> {
-#if (ATOMIC_LLONG_LOCK_FREE == 2)
+#if (ATOMIC_LLONG_LOCK_FREE == 2) || defined(GCC_USE_LIBATOMIC)
   using Type = T;
 #else
   static_assert(false,
@@ -224,7 +228,7 @@
 template <typename T>
 struct Largest_lock_free_type_selector<
     T, typename std::enable_if<std::is_integral<T>::value>::type> {
-#if (ATOMIC_LLONG_LOCK_FREE == 2)
+#if (ATOMIC_LLONG_LOCK_FREE == 2) || defined(GCC_USE_LIBATOMIC)
   using Type = std::conditional_t<std::is_unsigned<T>::value,
                                   unsigned long long, long long>;
 #elif (ATOMIC_LONG_LOCK_FREE == 2)


!DISABLE BREAKING ASSERTS!
--- a/storage/innobase/include/ut0ut.h	2025-09-24 21:35:03.000000000 +0800
+++ b/storage/innobase/include/ut0ut.h	2025-12-15 00:02:55.000000000 +0800
@@ -396,8 +396,9 @@
   /* Time when the last item was not throttled. Stored as number of seconds
   since epoch. */
   std::atomic<time_point> m_last_applied_time;
+#if !defined(__ppc__) && !defined(__i386__)
   static_assert(decltype(m_last_applied_time)::is_always_lock_free);
-
+#endif
   /** Throttle all items within that amount seconds from the last non throttled
   one. */
   const seconds m_throttle_delay;

--- a/storage/innobase/include/buf0buf.h	2025-09-24 21:35:03.000000000 +0800
+++ b/storage/innobase/include/buf0buf.h	2025-12-15 00:09:36.000000000 +0800
@@ -1819,7 +1819,9 @@
     btr_search_sys->parts[]->latch S-latch or X-latch is being held, or
     the block's lock is X-latched. */
     std::atomic<btr_search_prefix_info_t> prefix_info;
+#if !defined(__ppc__) && !defined(__i386__)
     static_assert(decltype(prefix_info)::is_always_lock_free);
+#endif
 
     /** Index for which the adaptive hash index has been created, or nullptr if
     the page does not exist in the index. Note that it does not guarantee that

--- a/storage/innobase/include/dict0mem.h	2025-09-24 21:35:03.000000000 +0800
+++ b/storage/innobase/include/dict0mem.h	2025-12-15 00:11:41.000000000 +0800
@@ -2426,8 +2426,9 @@
 
   /** Timestamp of the last modification of this table. */
   std::atomic<std::chrono::system_clock::time_point> update_time;
+#if !defined(__ppc__) && !defined(__i386__)
   static_assert(decltype(update_time)::is_always_lock_free);
-
+#endif
   /** row-id counter for use by intrinsic table for getting row-id.
   Given intrinsic table semantics, row-id can be locally maintained
   instead of getting it from central generator which involves mutex

--- a/storage/innobase/include/log0sys.h	2025-09-24 21:35:03.000000000 +0800
+++ b/storage/innobase/include/log0sys.h	2025-12-15 00:09:05.000000000 +0800
@@ -199,8 +199,9 @@
   the write/flush requests are not frequent. */
   alignas(ut::INNODB_CACHE_LINE_SIZE)
       std::atomic<std::chrono::microseconds> write_to_file_requests_interval;
+#if !defined(__ppc__) && !defined(__i386__)
   static_assert(decltype(write_to_file_requests_interval)::is_always_lock_free);
-
+#endif
   /** @} */
 
   /**************************************************/ /**

--- a/storage/innobase/include/trx0trx.h	2025-09-24 21:35:03.000000000 +0800
+++ b/storage/innobase/include/trx0trx.h	2025-12-15 00:49:28.000000000 +0800
@@ -924,7 +924,9 @@
   /** Time the state last time became TRX_STATE_ACTIVE. */
   std::atomic<std::chrono::system_clock::time_point> start_time{
       std::chrono::system_clock::time_point{}};
+#if !defined(__ppc__) && !defined(__i386__)
   static_assert(decltype(start_time)::is_always_lock_free);
+#endif
 
   lsn_t commit_lsn; /*!< lsn at the time of the commit */
 
--- a/storage/innobase/include/btr0sea.h	2025-09-24 21:35:03.000000000 +0800
+++ b/storage/innobase/include/btr0sea.h	2025-12-15 04:38:05.000000000 +0800
@@ -67,7 +67,9 @@
   /** @} */
 
   std::atomic<btr_search_prefix_info_t> prefix_info;
+#if !defined(__ppc__) && !defined(__i386__)
   static_assert(decltype(prefix_info)::is_always_lock_free);
+#endif
 #ifdef UNIV_SEARCH_PERF_STAT
   /** number of successful hash searches so far. */
   std::atomic<ulint> n_hash_succ;

--- a/storage/innobase/handler/ha_innodb.cc	2025-09-24 21:35:03.000000000 +0800
+++ b/storage/innobase/handler/ha_innodb.cc	2025-12-15 04:58:02.000000000 +0800
@@ -3380,7 +3380,9 @@
   /** The time when Validate_files::validate() starts or the last time
   one of the threads reported progress. */
   std::atomic<std::chrono::steady_clock::time_point> m_start_time;
+#if !defined(__ppc__) && !defined(__i386__)
   static_assert(decltype(m_start_time)::is_always_lock_free);
+#endif
 
   /** Number of tablespaces validated. */
   std::atomic_size_t m_n_validated;

--- a/storage/innobase/trx/trx0i_s.cc	2025-09-24 21:35:03.000000000 +0800
+++ b/storage/innobase/trx/trx0i_s.cc	2025-12-15 05:20:28.000000000 +0800
@@ -135,9 +135,9 @@
   /** last time the cache was read */
   std::atomic<std::chrono::steady_clock::time_point> last_read{
       std::chrono::steady_clock::time_point{}};
-
+#if !defined(__ppc__) && !defined(__i386__)
   static_assert(decltype(last_read)::is_always_lock_free);
-
+#endif
   /** innodb_trx table - contains i_s_trx_row_t objects */
   i_s_table_cache_t innodb_trx;
 
