[gtk/ebassi/popcount] Share the popcount() fallback for MSVC




commit b947ceb5cc45c40466b6d9d5f6454efec7099bbc
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Wed Dec 9 15:48:09 2020 +0000

    Share the popcount() fallback for MSVC
    
    We use __builtin_popcount() in a couple of places, so it makes sense to
    have it in one header.

 docs/reference/gtk/meson.build |  1 +
 gtk/gtkcssenumvalue.c          | 53 +++++++-------------------------------
 gtk/gtkmain.c                  |  9 ++++---
 gtk/gtkpopcountprivate.h       | 58 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 47 deletions(-)
---
diff --git a/docs/reference/gtk/meson.build b/docs/reference/gtk/meson.build
index b643adf676..8bac03063a 100644
--- a/docs/reference/gtk/meson.build
+++ b/docs/reference/gtk/meson.build
@@ -169,6 +169,7 @@ private_headers = [
   'gtkplacesviewprivate.h',
   'gtkplacesviewrowprivate.h',
   'gtkpointerfocusprivate.h',
+  'gtkpopcountprivate.h',
   'gtkpopoverprivate.h',
   'gtkprinterprivate.h',
   'gtkprintoperation-private.h',
diff --git a/gtk/gtkcssenumvalue.c b/gtk/gtkcssenumvalue.c
index 82d5580773..9bd29e3742 100644
--- a/gtk/gtkcssenumvalue.c
+++ b/gtk/gtkcssenumvalue.c
@@ -24,9 +24,7 @@
 #include "gtkstyleproviderprivate.h"
 #include "gtksettingsprivate.h"
 
-#ifdef _MSC_VER
-# include <intrin.h>
-#endif
+#include "gtkpopcountprivate.h"
 
 /* repeated API */
 
@@ -1453,39 +1451,6 @@ 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)
 {
@@ -1493,16 +1458,16 @@ east_asian_value_is_valid (GtkCssFontVariantEastAsian east_asian)
       (east_asian != GTK_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL))
     return FALSE;
 
-  if (__builtin_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS78 |
-                                        GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS83 |
-                                        GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS90 |
-                                        GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS04 |
-                                        GTK_CSS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED |
-                                        GTK_CSS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL)) > 1)
+  if (gtk_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS78 |
+                                  GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS83 |
+                                  GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS90 |
+                                  GTK_CSS_FONT_VARIANT_EAST_ASIAN_JIS04 |
+                                  GTK_CSS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED |
+                                  GTK_CSS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL)) > 1)
     return FALSE;
 
-  if (__builtin_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH |
-                                        GTK_CSS_FONT_VARIANT_EAST_ASIAN_PROPORTIONAL)) > 1)
+  if (gtk_popcount (east_asian & (GTK_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH |
+                                  GTK_CSS_FONT_VARIANT_EAST_ASIAN_PROPORTIONAL)) > 1)
     return FALSE;
 
   return TRUE;
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 13aa3dd10e..60e4a7b580 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -132,6 +132,7 @@
 #include "gtkimmodule.h"
 #include "gtkroot.h"
 #include "gtknative.h"
+#include "gtkpopcountprivate.h"
 
 #include "inspector/window.h"
 
@@ -1484,9 +1485,11 @@ handle_pointing_event (GdkEvent *event)
       modifiers = gdk_event_get_modifier_state (event);
 
       if (type == GDK_BUTTON_RELEASE &&
-          __builtin_popcount (modifiers &
-                              (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
-                               GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)) == 1)
+          gtk_popcount (modifiers & (GDK_BUTTON1_MASK |
+                                     GDK_BUTTON2_MASK |
+                                     GDK_BUTTON3_MASK |
+                                     GDK_BUTTON4_MASK |
+                                     GDK_BUTTON5_MASK)) == 1)
         {
           GtkWidget *new_target = gtk_widget_pick (native, x, y, GTK_PICK_DEFAULT);
 
diff --git a/gtk/gtkpopcountprivate.h b/gtk/gtkpopcountprivate.h
new file mode 100644
index 0000000000..cb06206845
--- /dev/null
+++ b/gtk/gtkpopcountprivate.h
@@ -0,0 +1,58 @@
+/* gtkpopcountprivate.h: Private implementation of popcount
+ *
+ * Copyright 2020  GNOME Foundation
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * This library 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 library 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 library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#ifdef _MSC_VER
+# include <intrin.h>
+#endif
+
+#ifdef _MSC_VER
+/* __builtin_popcount is a GCC-only function
+   so we need to define it for ourselves somehow */
+static inline guint
+gtk_popcount (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);
+}
+
+#else
+# define gtk_popcount(v) __builtin_popcount(v)
+#endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]