summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--volk/Makefile.common13
-rw-r--r--volk/include/volk/make_cpuid_x86_c.py3
-rw-r--r--volk/include/volk/make_set_simd.py33
-rw-r--r--volk/lib/Makefile.am2
-rw-r--r--volk/lib/assembly.h67
-rw-r--r--volk/lib/cpuid_x86.S60
-rw-r--r--volk/lib/cpuid_x86_64.S54
-rw-r--r--volk/lib/gcc_x86_cpuid.h178
8 files changed, 191 insertions, 219 deletions
diff --git a/volk/Makefile.common b/volk/Makefile.common
index daa8d78b6..e91a55e9c 100644
--- a/volk/Makefile.common
+++ b/volk/Makefile.common
@@ -26,19 +26,8 @@ if MD_CPU_generic
endif
if MD_CPU_x86
-if MD_SUBCPU_x86_64
platform_CODE = \
- $(top_srcdir)/lib/volk_cpu_x86.c \
- $(top_srcdir)/lib/cpuid_x86_64.S
-endif
-endif
-
-if MD_CPU_x86
-if !MD_SUBCPU_x86_64
- platform_CODE = \
- $(top_srcdir)/lib/volk_cpu_x86.c \
- $(top_srcdir)/lib/cpuid_x86.S
-endif
+ $(top_srcdir)/lib/volk_cpu_x86.c
endif
if MD_CPU_powerpc
diff --git a/volk/include/volk/make_cpuid_x86_c.py b/volk/include/volk/make_cpuid_x86_c.py
index 48a406fa4..2b2bd7c91 100644
--- a/volk/include/volk/make_cpuid_x86_c.py
+++ b/volk/include/volk/make_cpuid_x86_c.py
@@ -27,9 +27,10 @@ def make_cpuid_x86_c(dom) :
tempstring = tempstring + "/*this file is auto_generated by volk_register.py*/\n\n";
tempstring = tempstring + "#include <volk/volk_cpu.h>\n"
tempstring = tempstring + "#include <volk/volk_config_fixed.h>\n\n"
+ tempstring = tempstring + "#include <gcc_x86_cpuid.h>\n\n"
tempstring = tempstring + "struct VOLK_CPU volk_cpu;\n\n"
- tempstring = tempstring + "extern void cpuid_x86 (unsigned int op, unsigned int result[4]);\n\n"
+ tempstring = tempstring + "#define cpuid_x86(op, r) __get_cpuid(op, r+0, r+1, r+2, r+3)\n\n"
tempstring = tempstring + "static inline unsigned int cpuid_eax(unsigned int op) {\n";
tempstring = tempstring + " unsigned int regs[4];\n"
tempstring = tempstring + " cpuid_x86 (op, regs);\n"
diff --git a/volk/include/volk/make_set_simd.py b/volk/include/volk/make_set_simd.py
index 842366b18..275d3869f 100644
--- a/volk/include/volk/make_set_simd.py
+++ b/volk/include/volk/make_set_simd.py
@@ -27,30 +27,15 @@ def make_set_simd(dom) :
tempstring = tempstring + " AC_MSG_CHECKING([proccpu])\n";
tempstring = tempstring + " case \"$MD_CPU\" in\n";
tempstring = tempstring + " (x86)\n";
- tempstring = tempstring + " case \"$MD_SUBCPU\" in\n";
- tempstring = tempstring + " (x86)\n";
- tempstring = tempstring + " if test -z \"`${CC} -o proccpu -I $srcdir/include/ -I$srcdir/lib $srcdir/lib/volk_proccpu_sim.c $srcdir/lib/volk_cpu_x86.c $srcdir/lib/cpuid_x86.S`\"\n";
- tempstring = tempstring + " then\n";
- tempstring = tempstring + " AC_MSG_RESULT(yes)\n";
- tempstring = tempstring + " lv_PROCCPU=\"`./proccpu`\"\n";
- tempstring = tempstring + " rm -f proccpu\n";
- tempstring = tempstring + " else\n";
- tempstring = tempstring + " AC_MSG_RESULT(no)\n";
- tempstring = tempstring + " lv_PROCCPU=no\n";
- tempstring = tempstring + " fi\n"
- tempstring = tempstring + " ;;\n"
- tempstring = tempstring + " (*)\n"
- tempstring = tempstring + " if test -z \"`${CC} -o proccpu -I$srcdir/include/ -I$srcdir/lib $srcdir/lib/volk_proccpu_sim.c $srcdir/lib/volk_cpu_x86.c $srcdir/lib/cpuid_x86_64.S`\"\n";
- tempstring = tempstring + " then\n";
- tempstring = tempstring + " AC_MSG_RESULT(yes)\n";
- tempstring = tempstring + " lv_PROCCPU=\"`./proccpu`\"\n";
- tempstring = tempstring + " rm -f proccpu\n";
- tempstring = tempstring + " else\n";
- tempstring = tempstring + " AC_MSG_RESULT(no)\n";
- tempstring = tempstring + " lv_PROCCPU=no\n";
- tempstring = tempstring + " fi\n"
- tempstring = tempstring + " ;;\n"
- tempstring = tempstring + " esac\n"
+ tempstring = tempstring + " if test -z \"`${CC} -o proccpu -I$srcdir/include/ -I$srcdir/lib $srcdir/lib/volk_proccpu_sim.c $srcdir/lib/volk_cpu_x86.c 2>&1`\"\n";
+ tempstring = tempstring + " then\n";
+ tempstring = tempstring + " AC_MSG_RESULT(yes)\n";
+ tempstring = tempstring + " lv_PROCCPU=\"`./proccpu`\"\n";
+ tempstring = tempstring + " rm -f proccpu\n";
+ tempstring = tempstring + " else\n";
+ tempstring = tempstring + " AC_MSG_RESULT(no)\n";
+ tempstring = tempstring + " lv_PROCCPU=no\n";
+ tempstring = tempstring + " fi\n"
tempstring = tempstring + " ;;\n";
tempstring = tempstring + " (powerpc)\n";
tempstring = tempstring + " if test -z \"`${CC} -o proccpu -I$srcdir/include/ $srcdir/lib/volk_proccpu_sim.c $srcdir/lib/volk_cpu_powerpc.c 2>&1`\"\n";
diff --git a/volk/lib/Makefile.am b/volk/lib/Makefile.am
index 896d568e6..7a355e86a 100644
--- a/volk/lib/Makefile.am
+++ b/volk/lib/Makefile.am
@@ -186,7 +186,7 @@ libvolk_qa_la_LIBADD = \
noinst_HEADERS = \
volk_init.h \
qa_volk.h \
- assembly.h \
+ gcc_x86_cpuid.h \
qa_16s_quad_max_star_aligned16.h \
qa_32fc_dot_prod_aligned16.h \
qa_32fc_square_dist_aligned16.h \
diff --git a/volk/lib/assembly.h b/volk/lib/assembly.h
deleted file mode 100644
index 8a99aa07c..000000000
--- a/volk/lib/assembly.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2002 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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.
- *
- * GNU Radio 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef _ASSEMBLY_H_
-#define _ASSEMBLY_H_
-
-#if defined (__APPLE__) && defined (__APPLE_CC__)
-
-// XCode ignores the .scl and .type functions in XCode 2.2.1 and 2.3,
-// but creates an error in XCode 2.4. Just ignore them.
-
-#define GLOB_SYMB(f) _ ## f
-
-#define DEF_FUNC_HEAD(f) /* none */
-
-#define FUNC_TAIL(f) /* none*/
-
-#elif !defined (__ELF__)
-
-/*
- * Too bad, the following define does not work as expected --SF
- * #define GLOB_SYMB(f) __USER_LABEL_PREFIX__ ## f
- */
-#define GLOB_SYMB(f) _ ## f
-
-#define DEF_FUNC_HEAD(f) \
- .def GLOB_SYMB(f); .scl 2; .type 32; .endef
-
-#define FUNC_TAIL(f) /* none */
-
-
-#else /* !__ELF__ */
-
-
-#define GLOB_SYMB(f) f
-
-#define DEF_FUNC_HEAD(f) \
- .type GLOB_SYMB(f),@function \
-
-#define FUNC_TAIL(f) \
- .Lfe1: \
- .size GLOB_SYMB(f),.Lfe1-GLOB_SYMB(f)
-
-
-#endif /* !__ELF__ */
-
-
-#endif /* _ASSEMBLY_H_ */
diff --git a/volk/lib/cpuid_x86.S b/volk/lib/cpuid_x86.S
deleted file mode 100644
index 4e1a9404f..000000000
--- a/volk/lib/cpuid_x86.S
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# Copyright 2003 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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.
-#
-# GNU Radio 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.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-#
-# execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
-#
-# void cpuid_x86 (unsigned int op, unsigned int result[4]);
-#
-
-#include "assembly.h"
-
-.file "cpuid_x86.S"
- .version "01.01"
-.text
-.globl GLOB_SYMB(cpuid_x86)
- DEF_FUNC_HEAD(cpuid_x86)
-GLOB_SYMB(cpuid_x86):
- pushl %ebp
- movl %esp, %ebp
- pushl %ebx # must save in PIC mode, holds GOT pointer
- pushl %esi
-
- movl 8(%ebp), %eax # op
- movl 12(%ebp), %esi # result
- cpuid
- movl %eax, 0(%esi)
- movl %ebx, 4(%esi)
- movl %ecx, 8(%esi)
- movl %edx, 12(%esi)
-
- popl %esi
- popl %ebx
- popl %ebp
- ret
-
-FUNC_TAIL(cpuid_x86)
- .ident "Hand coded cpuid assembly"
-
-
-#if defined(__linux__) && defined(__ELF__)
-.section .note.GNU-stack,"",%progbits
-#endif
diff --git a/volk/lib/cpuid_x86_64.S b/volk/lib/cpuid_x86_64.S
deleted file mode 100644
index 32b1847cd..000000000
--- a/volk/lib/cpuid_x86_64.S
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Copyright 2003,2005 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio 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.
-#
-# GNU Radio 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.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-#
-# execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
-#
-# void cpuid_x86 (unsigned int op, unsigned int result[4]);
-#
-
-#include "assembly.h"
-
-.file "cpuid_x86_64.S"
- .version "01.01"
-.text
-.globl GLOB_SYMB(cpuid_x86)
- DEF_FUNC_HEAD(cpuid_x86)
-GLOB_SYMB(cpuid_x86):
- mov %rbx, %r11 # must save in PIC mode, holds GOT pointer
-
- mov %rdi, %rax # op
- cpuid
- movl %eax, 0(%rsi) # result
- movl %ebx, 4(%rsi)
- movl %ecx, 8(%rsi)
- movl %edx, 12(%rsi)
-
- mov %r11, %rbx
- retq
-
-FUNC_TAIL(cpuid_x86)
- .ident "Hand coded cpuid64 assembly"
-
-
-#if defined(__linux__) && defined(__ELF__)
-.section .note.GNU-stack,"",%progbits
-#endif
diff --git a/volk/lib/gcc_x86_cpuid.h b/volk/lib/gcc_x86_cpuid.h
new file mode 100644
index 000000000..2d0916fb3
--- /dev/null
+++ b/volk/lib/gcc_x86_cpuid.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+ *
+ * This file 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.
+ *
+ * This file 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/>.
+ */
+
+/* %ecx */
+#define bit_SSE3 (1 << 0)
+#define bit_PCLMUL (1 << 1)
+#define bit_SSSE3 (1 << 9)
+#define bit_FMA (1 << 12)
+#define bit_CMPXCHG16B (1 << 13)
+#define bit_SSE4_1 (1 << 19)
+#define bit_SSE4_2 (1 << 20)
+#define bit_MOVBE (1 << 22)
+#define bit_POPCNT (1 << 23)
+#define bit_AES (1 << 25)
+#define bit_XSAVE (1 << 26)
+#define bit_OSXSAVE (1 << 27)
+#define bit_AVX (1 << 28)
+
+/* %edx */
+#define bit_CMPXCHG8B (1 << 8)
+#define bit_CMOV (1 << 15)
+#define bit_MMX (1 << 23)
+#define bit_FXSAVE (1 << 24)
+#define bit_SSE (1 << 25)
+#define bit_SSE2 (1 << 26)
+
+/* Extended Features */
+/* %ecx */
+#define bit_LAHF_LM (1 << 0)
+#define bit_SSE4a (1 << 6)
+#define bit_SSE5 (1 << 11)
+
+/* %edx */
+#define bit_LM (1 << 29)
+#define bit_3DNOWP (1 << 30)
+#define bit_3DNOW (1 << 31)
+
+
+#if defined(__i386__) && defined(__PIC__)
+/* %ebx may be the PIC register. */
+#if __GNUC__ >= 3
+#define __cpuid(level, a, b, c, d) \
+ __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \
+ "cpuid\n\t" \
+ "xchg{l}\t{%%}ebx, %1\n\t" \
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d) \
+ __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \
+ "cpuid\n\t" \
+ "xchg{l}\t{%%}ebx, %1\n\t" \
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "0" (level), "2" (count))
+#else
+/* Host GCCs older than 3.0 weren't supporting Intel asm syntax
+ nor alternatives in i386 code. */
+#define __cpuid(level, a, b, c, d) \
+ __asm__ ("xchgl\t%%ebx, %1\n\t" \
+ "cpuid\n\t" \
+ "xchgl\t%%ebx, %1\n\t" \
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d) \
+ __asm__ ("xchgl\t%%ebx, %1\n\t" \
+ "cpuid\n\t" \
+ "xchgl\t%%ebx, %1\n\t" \
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "0" (level), "2" (count))
+#endif
+#else
+#define __cpuid(level, a, b, c, d) \
+ __asm__ ("cpuid\n\t" \
+ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
+ : "0" (level))
+
+#define __cpuid_count(level, count, a, b, c, d) \
+ __asm__ ("cpuid\n\t" \
+ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
+ : "0" (level), "2" (count))
+#endif
+
+/* Return highest supported input value for cpuid instruction. ext can
+ be either 0x0 or 0x8000000 to return highest supported value for
+ basic or extended cpuid information. Function returns 0 if cpuid
+ is not supported or whatever cpuid returns in eax register. If sig
+ pointer is non-null, then first four bytes of the signature
+ (as found in ebx register) are returned in location pointed by sig. */
+
+static __inline unsigned int
+__get_cpuid_max (unsigned int __ext, unsigned int *__sig)
+{
+ unsigned int __eax, __ebx, __ecx, __edx;
+
+#ifndef __x86_64__
+#if __GNUC__ >= 3
+ /* See if we can use cpuid. On AMD64 we always can. */
+ __asm__ ("pushf{l|d}\n\t"
+ "pushf{l|d}\n\t"
+ "pop{l}\t%0\n\t"
+ "mov{l}\t{%0, %1|%1, %0}\n\t"
+ "xor{l}\t{%2, %0|%0, %2}\n\t"
+ "push{l}\t%0\n\t"
+ "popf{l|d}\n\t"
+ "pushf{l|d}\n\t"
+ "pop{l}\t%0\n\t"
+ "popf{l|d}\n\t"
+ : "=&r" (__eax), "=&r" (__ebx)
+ : "i" (0x00200000));
+#else
+/* Host GCCs older than 3.0 weren't supporting Intel asm syntax
+ nor alternatives in i386 code. */
+ __asm__ ("pushfl\n\t"
+ "pushfl\n\t"
+ "popl\t%0\n\t"
+ "movl\t%0, %1\n\t"
+ "xorl\t%2, %0\n\t"
+ "pushl\t%0\n\t"
+ "popfl\n\t"
+ "pushfl\n\t"
+ "popl\t%0\n\t"
+ "popfl\n\t"
+ : "=&r" (__eax), "=&r" (__ebx)
+ : "i" (0x00200000));
+#endif
+
+ if (!((__eax ^ __ebx) & 0x00200000))
+ return 0;
+#endif
+
+ /* Host supports cpuid. Return highest supported cpuid input value. */
+ __cpuid (__ext, __eax, __ebx, __ecx, __edx);
+
+ if (__sig)
+ *__sig = __ebx;
+
+ return __eax;
+}
+
+/* Return cpuid data for requested cpuid level, as found in returned
+ eax, ebx, ecx and edx registers. The function checks if cpuid is
+ supported and returns 1 for valid cpuid information or 0 for
+ unsupported cpuid level. All pointers are required to be non-null. */
+
+static __inline int
+__get_cpuid (unsigned int __level,
+ unsigned int *__eax, unsigned int *__ebx,
+ unsigned int *__ecx, unsigned int *__edx)
+{
+ unsigned int __ext = __level & 0x80000000;
+
+ if (__get_cpuid_max (__ext, 0) < __level)
+ return 0;
+
+ __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx);
+ return 1;
+}