summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--volk/apps/CMakeLists.txt7
-rw-r--r--volk/gen/volk_arch_defs.py70
-rw-r--r--volk/gen/volk_machine_defs.py0
-rw-r--r--volk/gen/volk_tmpl_utils.py51
-rw-r--r--volk/gen/volk_xml_utils.py103
-rw-r--r--volk/tmpl/volk_cpu.tmpl.c170
-rw-r--r--volk/tmpl/volk_cpu.tmpl.h42
7 files changed, 439 insertions, 4 deletions
diff --git a/volk/apps/CMakeLists.txt b/volk/apps/CMakeLists.txt
index 14291e5e3..4af935fe6 100644
--- a/volk/apps/CMakeLists.txt
+++ b/volk/apps/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2011 Free Software Foundation, Inc.
+# Copyright 2011-2012 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -43,9 +43,8 @@ add_executable(volk_profile
target_link_libraries(volk_profile volk ${Boost_LIBRARIES})
install(
- PROGRAMS
- ${CMAKE_BINARY_DIR}/apps/volk_profile
- DESTINATION ${GR_RUNTIME_DIR}
+ PROGRAMS volk_profile
+ DESTINATION bin
COMPONENT "volk"
)
diff --git a/volk/gen/volk_arch_defs.py b/volk/gen/volk_arch_defs.py
new file mode 100644
index 000000000..271fc90c7
--- /dev/null
+++ b/volk/gen/volk_arch_defs.py
@@ -0,0 +1,70 @@
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import copy
+
+archs = list()
+
+class arch_class:
+ def __init__(self, **kwargs):
+ for key, cast, failval in (
+ ('name', str, None),
+ ('type', str, None),
+ ('no_test', bool, False),
+ ('val', int, None),
+ ('op', eval, None),
+ ('reg', int, None),
+ ('shift', int, None),
+ ('flag', str, None),
+ ('environment', str, None),
+ ('include', str, None),
+ ('alignment', int, 1),
+ ):
+ try: setattr(self, key, cast(kwargs[key]))
+ except: setattr(self, key, failval)
+ assert(self.name)
+ assert(self.type)
+
+ def __repr__(self): return self.name
+
+def register_arch(**kwargs):
+ arch = arch_class(**kwargs)
+ archs.append(arch)
+ if arch.alignment > 1:
+ kwargs['name'] += '_u'
+ kwargs['alignment'] = 1
+ register_arch(**kwargs)
+
+########################################################################
+# register the arches
+########################################################################
+#TODO skip the XML and put it here
+from xml.dom import minidom
+gendir = os.path.dirname(__file__)
+archs_xml = minidom.parse(os.path.join(gendir, 'archs.xml')).getElementsByTagName('arch')
+for arch_xml in archs_xml:
+ kwargs = dict()
+ for attr in arch_xml.attributes.keys():
+ kwargs[attr] = arch_xml.attributes[attr].value
+ for node in arch_xml.childNodes:
+ try:
+ name = node.tagName
+ val = arch_xml.getElementsByTagName(name)[0].firstChild.data
+ kwargs[name] = val
+ except: pass
+ register_arch(**kwargs)
diff --git a/volk/gen/volk_machine_defs.py b/volk/gen/volk_machine_defs.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/volk/gen/volk_machine_defs.py
diff --git a/volk/gen/volk_tmpl_utils.py b/volk/gen/volk_tmpl_utils.py
new file mode 100644
index 000000000..8b00f2f1f
--- /dev/null
+++ b/volk/gen/volk_tmpl_utils.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 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.
+#
+
+import os
+import re
+import volk_arch_defs
+from Cheetah import Template
+
+def __escape_pre_processor(code):
+ out = list()
+ for line in code.splitlines():
+ m = re.match('^(\s*)#(\s*)(\w+)(.*)$', line)
+ if m:
+ p0, p1, fcn, stuff = m.groups()
+ pponly = fcn in ('include', 'define', 'ifdef', 'ifndef', 'endif', 'elif')
+ both = fcn in ('if', 'else')
+ istmpl = '$' in stuff
+ if pponly or (both and not istmpl):
+ line = '%s\\#%s%s%s'%(p0, p1, fcn, stuff)
+ out.append(line)
+ return '\n'.join(out)
+
+def __parse_tmpl(_tmpl, **kwargs):
+ defs = {
+ 'archs': volk_arch_defs.archs,
+ }
+ defs.update(kwargs)
+ _tmpl = __escape_pre_processor(_tmpl)
+ return str(Template.Template(_tmpl, defs))
+
+import sys
+print __parse_tmpl(open(sys.argv[1]).read())
diff --git a/volk/gen/volk_xml_utils.py b/volk/gen/volk_xml_utils.py
new file mode 100644
index 000000000..05c0e1193
--- /dev/null
+++ b/volk/gen/volk_xml_utils.py
@@ -0,0 +1,103 @@
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+#this would not be necessary if we just skipped the xml part and stored the data in python
+
+import os
+from xml.dom import minidom
+import copy
+
+gendir = os.path.dirname(__file__)
+archs_xml = minidom.parse(os.path.join(gendir, 'archs.xml')).getElementsByTagName('arch')
+machines_xml = minidom.parse(os.path.join(gendir, 'machines.xml')).getElementsByTagName('machine')
+compilers_xml = minidom.parse(os.path.join(gendir, 'compilers.xml')).getElementsByTagName('compiler')
+
+class arch_class:
+ def __init__(self, arch_xml):
+ self.name = arch_xml.attributes['name'].value
+ self.type = arch_xml.attributes['type'].value
+ for key in ('val', 'op', 'reg', 'shift', 'flag', 'environment', 'include', 'alignment'):
+ try: setattr(self, key, arch_xml.getElementsByTagName(key)[0].firstChild.data)
+ except: setattr(self, key, None)
+ if self.alignment is None: self.alignment = 1
+
+ def __repr__(self): return self.name
+
+def get_archs():
+ adict = dict([(a.name, a) for a in map(arch_class, archs_xml)])
+ udict = dict()
+ for name, arch in adict.iteritems():
+ if arch.alignment == 1: continue
+ uarch = copy.deepcopy(arch)
+ uarch.name = arch.name + '_u'
+ uarch.alignment = 1
+ udict[uarch.name] = uarch
+ adict.update(udict)
+ return adict
+
+volk_archs = get_archs()
+
+class machine_class:
+ def __init__(self, name, archlist):
+ self.name = name
+ self.archs = list()
+ for arch_name in archlist:
+ if not arch_name: continue
+ self.archs.append(volk_archs[arch_name])
+ if volk_archs.has_key(arch_name + '_u'):
+ self.archs.append(volk_archs[arch_name + '_u'])
+
+ def __repr__(self): return self.name
+
+def yield_machines(name, archlist):
+ for i, arch_name in enumerate(archlist):
+ if '|' in arch_name:
+ for arch_sub in arch_name.split('|'):
+ for m in yield_machines(name, archlist[:i] + [arch_sub] + archlist[i+1:]):
+ yield m
+ return
+ yield machine_class(name, archlist)
+
+def get_machines():
+ mdict = dict()
+ for machine_xml in machines_xml:
+ name = machine_xml.attributes['name'].value
+ archlist = machine_xml.getElementsByTagName('archs')[0].firstChild.data.split()
+ for machine in yield_machines(name, archlist):
+ mdict[machine.name] = machine
+ return mdict
+
+volk_machines = get_machines()
+
+class compiler_class:
+ def __init__(self, compiler_xml):
+ self.name = compiler_xml.attributes['name'].value
+ self.prefix = compiler_xml.getElementsByTagName('prefix')[0].firstChild.data
+ self._remap = dict()
+ for remap_xml in compiler_xml.getElementsByTagName('remap'):
+ self._remap[remap_xml.attributes['name'].value] = remap_xml.firstChild.data
+
+ def remap(self, option):
+ if not self._remap.has_key(option): return option
+ return self._remap[option]
+
+ def __repr__(self): return self.name
+
+def get_compilers():
+ return dict([(c.name, c) for c in map(compiler_class, compilers_xml)])
+
+volk_compilers = get_compilers()
diff --git a/volk/tmpl/volk_cpu.tmpl.c b/volk/tmpl/volk_cpu.tmpl.c
new file mode 100644
index 000000000..dc24309f7
--- /dev/null
+++ b/volk/tmpl/volk_cpu.tmpl.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2011-2012 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.
+ */
+
+#include <volk/volk_cpu.h>
+#include <volk/volk_config_fixed.h>
+
+struct VOLK_CPU volk_cpu;
+
+#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
+# define VOLK_CPU_x86
+#endif
+
+#if defined(VOLK_CPU_x86)
+
+//implement get cpuid for gcc compilers using a copy of cpuid.h
+#if defined(__GNUC__)
+#include <gcc_x86_cpuid.h>
+#define cpuid_x86(op, r) __get_cpuid(op, (unsigned int *)r+0, (unsigned int *)r+1, (unsigned int *)r+2, (unsigned int *)r+3)
+
+//implement get cpuid for MSVC compilers using __cpuid intrinsic
+#elif defined(_MSC_VER)
+#include <intrin.h>
+#define cpuid_x86(op, r) __cpuid(r, op)
+
+#else
+#error "A get cpuid for volk is not available on this compiler..."
+#endif
+
+static inline unsigned int cpuid_eax(unsigned int op) {
+ int regs[4];
+ cpuid_x86 (op, regs);
+ return regs[0];
+}
+
+static inline unsigned int cpuid_ebx(unsigned int op) {
+ int regs[4];
+ cpuid_x86 (op, regs);
+ return regs[1];
+}
+
+static inline unsigned int cpuid_ecx(unsigned int op) {
+ int regs[4];
+ cpuid_x86 (op, regs);
+ return regs[2];
+}
+
+static inline unsigned int cpuid_edx(unsigned int op) {
+ int regs[4];
+ cpuid_x86 (op, regs);
+ return regs[3];
+}
+#endif
+
+#if defined(__arm__) && defined(__linux__)
+#include <asm/hwcap.h>
+#include <linux/auxvec.h>
+#include <stdio.h>
+#define LOOK_FOR_NEON
+#endif
+
+static int has_neon(void){
+#ifdef LOOK_FOR_NEON
+ FILE *auxvec_f;
+ unsigned long auxvec[2];
+ unsigned int found_neon = 0;
+ auxvec_f = fopen("/proc/self/auxv", "rb");
+ if(!auxvec_f) return 0;
+
+ //so auxv is basically 32b of ID and 32b of value
+ //so it goes like this
+ while(!found_neon && auxvec_f) {
+ fread(auxvec, sizeof(unsigned long), 2, auxvec_f);
+ if((auxvec[0] == AT_HWCAP) && (auxvec[1] & HWCAP_NEON))
+ found_neon = 1;
+ }
+
+ fclose(auxvec_f);
+ return found_neon;
+
+#else
+ return 0;
+}
+
+static int has_ppc(void){
+#ifdef __PPC__
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+#for $arch in $archs
+static int i_can_has_$arch.name () {
+########################################################################
+ #if $arch.type == "x86" and $arch.no_test
+#if defined(VOLK_CPU_x86)
+ return 1;
+#else
+ return 0;
+#endif
+########################################################################
+ #else if $arch.op == 1
+#if defined(VOLK_CPU_x86)
+ #set $op = hex($arch.op)
+ unsigned int e$(arch.reg)x = cpuid_e$(arch.reg)x ($op);
+ return ((e$(arch.reg)x >> $arch.shift) & 1) == $arch.val;
+#else
+ return 0;
+#endif
+########################################################################
+ #else if $arch.op == 0x80000001
+#if defined(VOLK_CPU_x86)
+ #set $op = hex($arch.op)
+ unsigned int extended_fct_count = cpuid_eax($op);
+ if (extended_fct_count < $op)
+ return $(arch.val)^1;
+ unsigned int extended_features = cpuid_e$(arch.reg)x ($op);
+ return ((extended_features >> $arch.shift) & 1) == $arch.val;
+#else
+ return 0;
+#endif
+########################################################################
+ #else if $arch.type == "powerpc"
+ return has_ppc();
+########################################################################
+ #else if $arch.type == "arm"
+ return has_neon();
+########################################################################
+ #else if $arch.type == "all"
+ return 1;
+########################################################################
+ #else ##$
+ return 0;
+ #end if
+}
+
+#end for
+
+void volk_cpu_init() {
+ #for $arch in $archs
+ volk_cpu.has_$arch.name = &i_can_has_$arch.name;
+ #end for
+}
+
+unsigned int volk_get_lvarch() {
+ unsigned int retval = 0;
+ volk_cpu_init();
+ #for $arch in $archs
+ retval += volk_cpu.has_$(arch.name)() << LV_$(arch.name.upper());
+ #end for
+ return retval;
+}
diff --git a/volk/tmpl/volk_cpu.tmpl.h b/volk/tmpl/volk_cpu.tmpl.h
new file mode 100644
index 000000000..4d66512e1
--- /dev/null
+++ b/volk/tmpl/volk_cpu.tmpl.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011-2012 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 INCLUDED_VOLK_CPU_H
+#define INCLUDED_VOLK_CPU_H
+
+#include <volk/volk_common.h>
+
+__VOLK_DECL_BEGIN
+
+struct VOLK_CPU {
+ #for $arch in $archs
+ int (*has_$arch.name) ();
+ #end for
+};
+
+extern struct VOLK_CPU volk_cpu;
+
+void volk_cpu_init ();
+unsigned int volk_get_lvarch ();
+
+__VOLK_DECL_END
+
+#endif /*INCLUDED_VOLK_CPU_H*/