gtk/gtkcssenumvalue.c: Deal with __builtin_popcount on MSVC
__builtin_popcount is a GCCism that is used to count the number of bits involved, which means any non GCC/CLang compilers won't like the code, meaning that on MSVC builds we must implement it ourselves. We first use __cpuid() to check whether the CPU supports the popcount instruction, if it does, we use the __popcnt intrinsic, otherwise (untested, since I don't have a system that does not have the instruction), we use the suggested hacks at http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel https://bugzilla.gnome.org/show_bug.cgi?id=773299
This commit is contained in:
@@ -24,6 +24,10 @@
|
||||
#include "gtkstyleproviderprivate.h"
|
||||
#include "gtksettingsprivate.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
/* repeated API */
|
||||
|
||||
struct _GtkCssValue {
|
||||
@@ -1429,6 +1433,39 @@ static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT_EAST_ASIAN = {
|
||||
gtk_css_font_variant_east_asian_value_print
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* __builtin_popcount is a GCC-only function
|
||||
so we need to define it for ourselves somehow */
|
||||
|
||||
static inline guint
|
||||
__msvc_compat_popcnt (guint32 value)
|
||||
{
|
||||
static gssize popcnt_checked = 0;
|
||||
static gboolean have_popcnt = FALSE;
|
||||
|
||||
# if defined (_M_AMD64) || defined (_M_X64) || (_M_IX86)
|
||||
if (g_once_init_enter (&popcnt_checked))
|
||||
{
|
||||
int cpuinfo[4] = {-1};
|
||||
|
||||
__cpuid (cpuinfo, 1);
|
||||
have_popcnt = (cpuinfo[2] & 0x00800000) != 0;
|
||||
g_once_init_leave (&popcnt_checked, 1);
|
||||
}
|
||||
# endif
|
||||
|
||||
if (have_popcnt)
|
||||
return __popcnt (value);
|
||||
else
|
||||
/* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel */
|
||||
return (((value & 0xfff) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) +
|
||||
((((value & 0xfff000) >> 12) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f) +
|
||||
(((value >> 24) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f);
|
||||
}
|
||||
|
||||
# define __builtin_popcount(v) __msvc_compat_popcnt(v)
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
east_asian_value_is_valid (GtkCssFontVariantEastAsian east_asian)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user