This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Move the popcnt intrinsics to a separate file


Hi,

The attached patch moves __popcntd, __popcntq, _popcnt64, _popcnt32,
_mm_popcnt_u32, and _mm_popcnt_u64 to a separate file popcount.h.
popcount.h is then included in abmintrin.h and smmintrin.h.

The rationale behind this change is that ia32intrin.h is included by
default in x86intrin.h without any architecture checks, and so
ia32intrin.h is too general for the popcnt instructions: e.g., k8 does
not have popcnt instructions, and currently we would have these
intrinsics defined even for k8.

2009-11-19  Sebastian Pop  <sebastian.pop@amd.com>

	* config.gcc (extra_headers): Add abmintrin.h and popcount.h for
	i[34567]86-*-* and x86_64-*-*.
	* config/i386/abmintrin.h: New.
	* config/i386/i386-c.c (ix86_target_macros_internal): Defined __ABM__.
	* config/i386/ia32intrin.h (__popcntd, __popcntq, _popcnt64,
	_popcnt32): Moved...
	* config/i386/popcount.h: ...here.  New file.
	* config/i386/smmintrin.h: Include popcount.h.
	(_mm_popcnt_u32, _mm_popcnt_u64): Moved to popcount.h.
	* config/i386/x86intrin.h: Include abmintrin.h when __ABM__ is defined.

Bootstrapped and tested on amd64-linux.  Ok for trunk?

Thanks,
Sebastian Pop
--
AMD / Open Source Compiler Engineering / GNU Tools
From a3176c8b6000af222e71800f91c622d87d2af4e9 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <sebpop@gmail.com>
Date: Tue, 10 Nov 2009 10:47:07 -0600
Subject: [PATCH] popcount

2009-11-19  Sebastian Pop  <sebastian.pop@amd.com>

	* config.gcc (extra_headers): Add abmintrin.h and popcount.h for
	i[34567]86-*-* and x86_64-*-*.
	* config/i386/abmintrin.h: New.
	* config/i386/i386-c.c (ix86_target_macros_internal): Defined __ABM__.
	* config/i386/ia32intrin.h (__popcntd, __popcntq, _popcnt64,
	_popcnt32): Moved...
	* config/i386/popcount.h: ...here.  New file.
	* config/i386/smmintrin.h: Include popcount.h.
	(_mm_popcnt_u32, _mm_popcnt_u64): Moved to popcount.h.
	* config/i386/x86intrin.h: Include abmintrin.h when __ABM__ is defined.
---
 gcc/config.gcc               |    6 ++-
 gcc/config/i386/abmintrin.h  |   39 ++++++++++++++++++++++
 gcc/config/i386/i386-c.c     |    2 +
 gcc/config/i386/ia32intrin.h |   18 ----------
 gcc/config/i386/popcount.h   |   73 ++++++++++++++++++++++++++++++++++++++++++
 gcc/config/i386/smmintrin.h  |   15 +--------
 gcc/config/i386/x86intrin.h  |    4 ++
 7 files changed, 123 insertions(+), 34 deletions(-)
 create mode 100644 gcc/config/i386/abmintrin.h
 create mode 100644 gcc/config/i386/popcount.h

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 90aa7a7..2620f4e 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -288,7 +288,8 @@ i[34567]86-*-*)
 		       pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
 		       nmmintrin.h bmmintrin.h fma4intrin.h wmmintrin.h
 		       immintrin.h x86intrin.h avxintrin.h xopintrin.h
-		       ia32intrin.h cross-stdarg.h lwpintrin.h"
+		       ia32intrin.h cross-stdarg.h lwpintrin.h abmintrin.h
+		       popcount.h"
 	;;
 x86_64-*-*)
 	cpu_type=i386
@@ -298,7 +299,8 @@ x86_64-*-*)
 		       pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
 		       nmmintrin.h bmmintrin.h fma4intrin.h wmmintrin.h
 		       immintrin.h x86intrin.h avxintrin.h xopintrin.h
-		       ia32intrin.h cross-stdarg.h lwpintrin.h"
+		       ia32intrin.h cross-stdarg.h lwpintrin.h abmintrin.h
+		       popcount.h"
 	need_64bit_hwint=yes
 	;;
 ia64-*-*)
diff --git a/gcc/config/i386/abmintrin.h b/gcc/config/i386/abmintrin.h
new file mode 100644
index 0000000..8df4d49
--- /dev/null
+++ b/gcc/config/i386/abmintrin.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC 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 General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _X86INTRIN_H_INCLUDED
+# error "Never use <abmintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef _ABMINTRIN_H_INCLUDED
+#define _ABMINTRIN_H_INCLUDED
+
+#ifndef __ABM__
+# error "ABM instruction set not enabled"
+#else
+
+#include <popcount.h>
+
+#endif /* __ABM__ */
+
+#endif /* _ABMINTRIN_H_INCLUDED */
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index 5a5311f..cba9ceb 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -236,6 +236,8 @@ ix86_target_macros_internal (int isa_flag,
     def_or_undef (parse_in, "__XOP__");
   if (isa_flag & OPTION_MASK_ISA_LWP)
     def_or_undef (parse_in, "__LWP__");
+  if (isa_flag & OPTION_MASK_ISA_ABM)
+    def_or_undef (parse_in, "__ABM__");
   if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE))
     def_or_undef (parse_in, "__SSE_MATH__");
   if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE2))
diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h
index 540bc3f..783964c 100644
--- a/gcc/config/i386/ia32intrin.h
+++ b/gcc/config/i386/ia32intrin.h
@@ -73,14 +73,6 @@ __crc32d (unsigned int __C, unsigned int __V)
 }
 #endif /* SSE4.2 */
 
-/* 32bit popcnt */
-extern __inline int
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
-__popcntd (unsigned int __X)
-{
-  return __builtin_popcount (__X);
-}
-
 /* rdpmc */
 extern __inline unsigned long long
 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -186,14 +178,6 @@ __crc32q (unsigned long long __C, unsigned long long __V)
   return __builtin_ia32_crc32di (__C, __V);
 }
 
-/* 64bit popcnt */
-extern __inline long long
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
-__popcntq (unsigned long long __X)
-{
-  return __builtin_popcountll (__X);
-}
-
 /* 64bit rol */
 extern __inline unsigned long long
 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -211,7 +195,6 @@ __rorq (unsigned long long __X, int __C)
 }
 
 #define _bswap64(a)		__bswapq(a)
-#define _popcnt64(a)		__popcntq(a)
 #define _lrotl(a,b)		__rolq((a), (b))
 #define _lrotr(a,b)		__rorq((a), (b))
 #else
@@ -222,7 +205,6 @@ __rorq (unsigned long long __X, int __C)
 #define _bit_scan_forward(a)	__bsfd(a)
 #define _bit_scan_reverse(a)	__bsrd(a)
 #define _bswap(a)		__bswapd(a)
-#define _popcnt32(a)		__popcntd(a)
 #define _rdpmc(a)		__rdpmc(a)
 #define _rdtsc()		__rdtsc()
 #define _rdtscp(a)		__rdtscp(a)
diff --git a/gcc/config/i386/popcount.h b/gcc/config/i386/popcount.h
new file mode 100644
index 0000000..604c078
--- /dev/null
+++ b/gcc/config/i386/popcount.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC 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 General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _X86INTRIN_H_INCLUDED
+# ifndef _SMMINTRIN_H_INCLUDED
+#  error "Never use <popcount.h> directly; include <x86intrin.h> instead."
+# endif
+#endif
+
+#ifndef _POPCOUNT_H_INCLUDED
+#define _POPCOUNT_H_INCLUDED
+
+/* 32bit popcnt */
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__popcntd (unsigned int __X)
+{
+  return __builtin_popcount (__X);
+}
+
+#ifdef __x86_64__
+/* 64bit popcnt */
+extern __inline long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__popcntq (unsigned long long __X)
+{
+  return __builtin_popcountll (__X);
+}
+#endif
+
+#define _popcnt64(a)		__popcntq(a)
+#define _popcnt32(a)		__popcntd(a)
+
+#ifdef __SSE4_2__
+
+/* Calculate a number of bits set to 1.  */
+extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_popcnt_u32 (unsigned int __X)
+{
+  return __builtin_popcount (__X);
+}
+
+#ifdef __x86_64__
+extern __inline long long  __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_popcnt_u64 (unsigned long long __X)
+{
+  return __builtin_popcountll (__X);
+}
+#endif /* __x86_64__ */
+
+#endif /* __SSE4_2__ */
+
+#endif /* _POPCOUNT_H_INCLUDED */
diff --git a/gcc/config/i386/smmintrin.h b/gcc/config/i386/smmintrin.h
index 8fbb35c..58737d9 100644
--- a/gcc/config/i386/smmintrin.h
+++ b/gcc/config/i386/smmintrin.h
@@ -793,20 +793,7 @@ _mm_cmpgt_epi64 (__m128i __X, __m128i __Y)
   return (__m128i) __builtin_ia32_pcmpgtq ((__v2di)__X, (__v2di)__Y);
 }
 
-/* Calculate a number of bits set to 1.  */
-extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm_popcnt_u32 (unsigned int __X)
-{
-  return __builtin_popcount (__X);
-}
-
-#ifdef __x86_64__
-extern __inline long long  __attribute__((__gnu_inline__, __always_inline__, __artificial__))
-_mm_popcnt_u64 (unsigned long long __X)
-{
-  return __builtin_popcountll (__X);
-}
-#endif
+#include <popcount.h>
 
 /* Accumulate CRC32 (polynomial 0x11EDC6F41) value.  */
 extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
diff --git a/gcc/config/i386/x86intrin.h b/gcc/config/i386/x86intrin.h
index ac7e21f..63252bf 100644
--- a/gcc/config/i386/x86intrin.h
+++ b/gcc/config/i386/x86intrin.h
@@ -77,4 +77,8 @@
 #include <lwpintrin.h>
 #endif
 
+#ifdef __ABM__
+#include <abmintrin.h>
+#endif
+
 #endif /* _X86INTRIN_H_INCLUDED */
-- 
1.6.0.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]