From e5e8baa86fbeb4195176cf7b5d9edba18baff5fe Mon Sep 17 00:00:00 2001 From: Lukas Fittl Date: Fri, 29 Dec 2023 15:36:26 -0800 Subject: [PATCH] Optionally support 32-bit builds This can be useful when building for WASM targets, as well as for legacy systems that run on 32-bit. The relevant code is enabled at compile time by checking the pointer size (__SIZEOF_POINTER__ == 4). --- Makefile | 22 ++++++++++++++++++++++ scripts/extract_source.rb | 6 ++++++ src/postgres/include/pg_config.h | 21 +++++++++++++++++++++ src/postgres/src_port_pg_bitutils.c | 22 +++++++++++++++++++++- 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 75d42e17..50730e32 100644 --- a/Makefile +++ b/Makefile @@ -153,6 +153,28 @@ $(PGDIR): echo "#if defined(__FreeBSD__) || defined(__NetBSD__) || (defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 38) || __GLIBC__ > 2))" >> $(PGDIR)/src/include/pg_config.h echo "#define HAVE_STRCHRNUL" >> $(PGDIR)/src/include/pg_config.h echo "#endif" >> $(PGDIR)/src/include/pg_config.h + # Optionally support 32-bit + echo "#if defined(_WIN32) || __SIZEOF_POINTER__ == 4" >> $(PGDIR)/src/include/pg_config.h + echo "#undef ALIGNOF_DOUBLE" >> $(PGDIR)/src/include/pg_config.h + echo "#define ALIGNOF_DOUBLE 4" >> $(PGDIR)/src/include/pg_config.h + echo "#undef ALIGNOF_LONG" >> $(PGDIR)/src/include/pg_config.h + echo "#define ALIGNOF_LONG 4" >> $(PGDIR)/src/include/pg_config.h + echo "#define ALIGNOF_LONG_LONG_INT 4" >> $(PGDIR)/src/include/pg_config.h + echo "#undef ALIGNOF_PG_INT128_TYPE" >> $(PGDIR)/src/include/pg_config.h + echo "#undef HAVE_LONG_INT_64" >> $(PGDIR)/src/include/pg_config.h + echo "#define HAVE_LONG_LONG_INT_64 1" >> $(PGDIR)/src/include/pg_config.h + echo "#undef INT64_MODIFIER" >> $(PGDIR)/src/include/pg_config.h + echo "#define INT64_MODIFIER "ll"" >> $(PGDIR)/src/include/pg_config.h + echo "#undef PG_INT128_TYPE" >> $(PGDIR)/src/include/pg_config.h + echo "#undef PG_INT64_TYPE" >> $(PGDIR)/src/include/pg_config.h + echo "#define PG_INT64_TYPE long long int" >> $(PGDIR)/src/include/pg_config.h + echo "#undef SIZEOF_LONG" >> $(PGDIR)/src/include/pg_config.h + echo "#define SIZEOF_LONG 4" >> $(PGDIR)/src/include/pg_config.h + echo "#undef SIZEOF_SIZE_T" >> $(PGDIR)/src/include/pg_config.h + echo "#define SIZEOF_SIZE_T 4" >> $(PGDIR)/src/include/pg_config.h + echo "#undef SIZEOF_VOID_P" >> $(PGDIR)/src/include/pg_config.h + echo "#define SIZEOF_VOID_P 4" >> $(PGDIR)/src/include/pg_config.h + echo "#endif" >> $(PGDIR)/src/include/pg_config.h extract_source: $(PGDIR) -@ $(RM) -rf ./src/postgres/ diff --git a/scripts/extract_source.rb b/scripts/extract_source.rb index bf5224a2..92c8a99b 100644 --- a/scripts/extract_source.rb +++ b/scripts/extract_source.rb @@ -586,6 +586,12 @@ def write_out # Other required functions runner.deep_resolve('pg_printf') +# Retain these functions for optional 32-bit support +# (see BITS_PER_BITMAPWORD checks in bitmapset.c) +runner.deep_resolve('pg_leftmost_one_pos32') +runner.deep_resolve('pg_rightmost_one_pos32') +runner.deep_resolve('pg_popcount32') + runner.write_out #puts runner.unresolved.inspect diff --git a/src/postgres/include/pg_config.h b/src/postgres/include/pg_config.h index d1dd7b72..30823be1 100644 --- a/src/postgres/include/pg_config.h +++ b/src/postgres/include/pg_config.h @@ -841,3 +841,24 @@ #if defined(__FreeBSD__) || defined(__NetBSD__) || (defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 38) || __GLIBC__ > 2)) #define HAVE_STRCHRNUL #endif +#if defined(_WIN32) || __SIZEOF_POINTER__ == 4 +#undef ALIGNOF_DOUBLE +#define ALIGNOF_DOUBLE 4 +#undef ALIGNOF_LONG +#define ALIGNOF_LONG 4 +#define ALIGNOF_LONG_LONG_INT 4 +#undef ALIGNOF_PG_INT128_TYPE +#undef HAVE_LONG_INT_64 +#define HAVE_LONG_LONG_INT_64 1 +#undef INT64_MODIFIER +#define INT64_MODIFIER ll +#undef PG_INT128_TYPE +#undef PG_INT64_TYPE +#define PG_INT64_TYPE long long int +#undef SIZEOF_LONG +#define SIZEOF_LONG 4 +#undef SIZEOF_SIZE_T +#define SIZEOF_SIZE_T 4 +#undef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif diff --git a/src/postgres/src_port_pg_bitutils.c b/src/postgres/src_port_pg_bitutils.c index aa6514ad..efac6ad2 100644 --- a/src/postgres/src_port_pg_bitutils.c +++ b/src/postgres/src_port_pg_bitutils.c @@ -2,6 +2,8 @@ * Symbols referenced in this file: * - pg_popcount64 * - pg_popcount64_slow + * - pg_popcount32 + * - pg_popcount32_slow *-------------------------------------------------------------------- */ @@ -175,9 +177,23 @@ __asm__ __volatile__(" popcntq %1,%0\n":"=q"(res):"rm"(word):"cc"); * pg_popcount32_slow * Return the number of 1 bits set in word */ +static int +pg_popcount32_slow(uint32 word) +{ #ifdef HAVE__BUILTIN_POPCOUNT + return __builtin_popcount(word); #else /* !HAVE__BUILTIN_POPCOUNT */ + int result = 0; + + while (word != 0) + { + result += pg_number_of_ones[word & 255]; + word >>= 8; + } + + return result; #endif /* HAVE__BUILTIN_POPCOUNT */ +} /* * pg_popcount64_slow @@ -216,7 +232,11 @@ pg_popcount64_slow(uint64 word) * TRY_POPCNT_FAST is not defined. The compiler should be able to inline * the slow versions here. */ - +int +pg_popcount32(uint32 word) +{ + return pg_popcount32_slow(word); +} int pg_popcount64(uint64 word)