diff options
Diffstat (limited to 'volk')
-rw-r--r-- | volk/Makefile.common | 13 | ||||
-rw-r--r-- | volk/include/volk/make_cpuid_x86_c.py | 3 | ||||
-rw-r--r-- | volk/include/volk/make_set_simd.py | 33 | ||||
-rw-r--r-- | volk/lib/Makefile.am | 2 | ||||
-rw-r--r-- | volk/lib/assembly.h | 67 | ||||
-rw-r--r-- | volk/lib/cpuid_x86.S | 60 | ||||
-rw-r--r-- | volk/lib/cpuid_x86_64.S | 54 | ||||
-rw-r--r-- | volk/lib/gcc_x86_cpuid.h | 178 |
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; +} |